1

I have the following simple Verilog design (in test.v):

module digital (
  input a, b, c,
  output reg q
);
  wire ena = a & b;
  always @ (ena, c) begin
    if (ena)
      q <= c;
  end
endmodule

Which models a simple latch with a gate on it's ena input. I am using the following Yosys TCL script:

yosys -import
set name digital
set libfile my_tech.lib
read_liberty -lib $libfile
read_verilog test.v
hierarchy -check -top ${name}
procs; opt
memory; opt
fsm -norecode; opt -full
techmap; opt -full
dfflibmap -liberty $libfile
opt
abc -liberty $libfile \
    -script {+strash;ifraig;scorr;dc2;dretime;strash;&get,-n;&dch,-f;&nf,{D};&put}
hilomap -hicell TIEHIM Y -locell TIELOM Y
clean -purge
write_verilog ${name}_synth.v

Even though DFFs are mapped fine (I tried with a different design), the resulting Verilog file includes an instance of a \$_DLATCH_P_ cell.

So I tried to follow the note in this comment, i.e. writing a custom tech map file to map Yosys latches to the ones from the tech library:

1. Using the template I got from the yosys command help $dlatch+ and looking at some examples in the built-in Yosys techmap, I created what I believe to be a mapping file, test_map.v to use the library's own TLATX1M latch cell:

(* techmap_simplemap *)
(* techmap_celltype = "$dlatch" *)
module _library_latch (EN, D, Q);

    parameter WIDTH = 0;
    parameter EN_POLARITY = 1'b1;

    input EN;
    input [WIDTH-1:0] D;
    output reg [WIDTH-1:0] Q;

    genvar i;
    generate begin
        for (i = 0; i < WIDTH; i=i+1) begin:latch_bit
          TLATX1M _TECHMAP_REPLACE_ (  // TODO: support EN_POLARITY = 1'b0
            .D(D[i]),
            .G(EN),
            .Q(Q[i]),
            .QN()
          );
        end
    end endgenerate

endmodule

2. Then I also added the line techmap -map test_map.v after the techmap; opt -full line in my synthesis script.

Unfortunately, without success: There still is a \$_DLATCH_P_ instance in the Yosys output netlist. I also couldn't find any related warnings/errors in the Yosys log output.

3. I also tried to change the module name of the mapping cell (_library_latch in the code above) and/or the techmap_celltype comment to \$_DLATCH_P_, but that didn't help either.

What am I missing?

FriendFX
  • 2,929
  • 1
  • 34
  • 63

1 Answers1

2

After finding the official Yosys latch mapping file for the ICE40 FPGA, I changed the test_map.v file to the following:

module \$_DLATCH_N_ (E, D, Q);
  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
  input E, D;
  output Q;
  TLATNX1M _TECHMAP_REPLACE_ (
    .D(D),
    .GN(E),
    .Q(Q),
    .QN()
  );
endmodule

module \$_DLATCH_P_ (E, D, Q);
  wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
  input E, D;
  output Q;
  TLATX1M _TECHMAP_REPLACE_ (
    .D(D),
    .G(E),
    .Q(Q),
    .QN()
  );
endmodule

...and the techmap -map test_map.v line in my Yosys script was already correct, here's the entire file for reference:

yosys -import
set name digital
set libfile my_tech.lib
read_liberty -lib $libfile
read_verilog test.v
hierarchy -check -top ${name}
procs; opt
memory; opt
fsm -norecode; opt -full
techmap; opt -full
techmap -map test_map.v
dfflibmap -liberty $libfile
opt
abc -liberty $libfile \
    -script {+strash;ifraig;scorr;dc2;dretime;strash;&get,-n;&dch,-f;&nf,{D};&put}
hilomap -hicell TIEHIM Y -locell TIELOM Y
clean -purge
write_verilog ${name}_synth.v

Now the output netlist has an instance like so:

  TLATX1M _1_ (
    .D(c),
    .G(ena),
    .Q(q),
    .QN()
  );
FriendFX
  • 2,929
  • 1
  • 34
  • 63
  • Note that the `wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";` shouldn't be needed here - the iCE40 rules have it because they use soft logic to implement the latches which itself needs to be mapped; in this case a cell instance doesn't need that. – gatecat Feb 10 '20 at 13:55