1

I am trying to assign an initial value to the FF at reset. The initial value is an input to the circuit. In the cell library I added the following FF:

cell (DFF){
    area    : 0;
    ff(IQ,IQN){
        next_state  : "D";
        clocked_on  : "CLK";
        clear   : "I'*RST";
        preset  : "I*RST";
        clear_preset_var1   : L;
    }
    pin(CLK){
        direction   : input;
        capacitance : 0;
        clock   : true;
    }
    pin(RST){
        direction   : input;
        capacitance : 0;
    }
    pin(D){
        direction   : input;
        capacitance : 0;
        timing() {
          related_pin   : "CLK";
        }
    }
    pin(I){
        direction   : input;
        capacitance : 0;
    }
    pin(Q){
        direction   : output;
        function    : "IQ";
        timing() {
          related_pin   : "CLK";
          timing_type   : falling_edge;
        }
        timing() {
            related_pin : "RST";
            timing_type : clear;
            timing_sense    : positive_unate;
        }
        timing() {
            related_pin : "I";
            timing_type : clear;
            timing_sense    : negative_unate;
        }
        timing() {
            related_pin : "RST";
            timing_type : preset;
            timing_sense    : positive_unate;
        }
        timing() {
            related_pin : "I";
            timing_type : preset;
            timing_sense    : positive_unate;
        }
    }
}

The part of the Verilog code that I am trying to synthesize to this FF is

    always@(posedge clk or posedge rst)
    if(rst) begin 
        e_reg <= e_input;
    end
    else begin 
        e_reg <= e_shift;
    end 

However, when I run the synthesis, it uses one of the built-in FFs from the Yosys library ($_DFFSR_PPP_) ignoring the one from the user-defined cell library. If I include one of the set-reset (SR) FFs in the user-defined library, like the following, that is picked up by Yosys.

cell(DFF) {
area: 0;
ff("IQ", "IQN") { clocked_on: CLK;
              next_state: D;
                  preset: I;
                   clear: RST; }
pin(CLK) { direction: input;
             clock: true; }
pin(D) { direction: input; }
pin(Q) { direction: output;
          function: "IQ"; }
pin(I) { direction: input; }
pin(RST) { direction: input; }
}

The earlier one works with Synopsys DC, but not with Yosys. It seems that the equations in clear or preset are not being picked up by Yosys.

In there any way to make it work? Am I missing something?

EDIT: I am adding a complete example in case anyone wants to run this.

acc.v

module acc #(parameter N = 1)( 
    input clk,
    input rst,
    input [N-1:0] a,
    input [N-1:0] b,
    output [N-1:0] o
);

    logic [N-1:0] o_reg;

    assign o = o_reg & a;

    always@(posedge clk or posedge rst) begin
        if(rst) o_reg <= b;
        else o_reg <= o;
    end 

endmodule

asic_cell_yosys.lib

library(demo) {
    cell(IV) {
        area: 1;
        pin(A) { direction: input; }
        pin(Z) { direction: output; function: "A'"; }
    }
    cell(AND) {
        area: 1;
        pin(A) { direction: input; }
        pin(B) { direction: input; }
        pin(Z) { direction: output; function: "(A&B)"; }
    }   
    cell(NAND) {
        area: 1;
        pin(A) { direction: input; }
        pin(B) { direction: input; }
        pin(Z) { direction: output; function: "(A&B)'"; }
    }
    cell(DFFSR) {
        area: 4;
        ff("IQ", "IQN"){clocked_on: C;
                        next_state: D;
                        preset: S;
                        clear: R; }
        pin(C) { direction: input;
                     clock: true; }
        pin(D) { direction: input; }
        pin(Q) { direction: output;
                  function: "IQ"; }
        pin(S) { direction: input; }
        pin(R) { direction: input; }
    }
}

acc.tcl

yosys -import
read_verilog -sv acc.sv
hierarchy -check -top acc 
procs; opt; flatten; opt; 
techmap; opt;
dfflibmap -liberty asic_cell_yosys.lib
abc -liberty asic_cell_yosys.lib -script +map; 
opt; clean; opt;
opt_clean -purge
write_verilog -noattr -noexpr -nohex acc_syn.v
Siam
  • 95
  • 1
  • 7

1 Answers1

1

Yosys' dfflibmap doesn't support expressions such as this for clear or preset in a Liberty file.

However, you could use the techmap command with a custom-made map rule to map $_DFFSR_PPP_ to your own flipflop - similar to how we do FPGA techmapping in Yosys.

As an example of this. Create dffsr_map.v:

module $_DFFSR_PPP_(input C, S, R, D, output Q);
    DFFSR _TECHMAP_REPLACE_ (.CLK(C), .RST(S | R), .I(S), .D(D), .Q(Q));    
endmodule

and add techmap -map dffsr_map.v -map +/techmap.v after dfflibmap

gatecat
  • 1,156
  • 2
  • 8
  • 15
  • Apologies for re-opening this after so long. Could you point me to any tutorial or example code that will help me understand the steps of using `techmap`? – Siam Sep 12 '19 at 00:31
  • I have edited the post to provide a complete example. – Siam Sep 12 '19 at 00:40
  • Thanks a lot for the example. It works now. However, there is still one small redundancy. The input to the `I` port is `b&rst`. Since the `DFF` only reads the `I` port when `rst` is high, this AND operation is redundant. I think the reason for this is that abc does not know about this property of the `DFF` specification. Is it possible to get rid of this AND gate? (The current output is good enough anyway). – Siam Sep 17 '19 at 18:36