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
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