mirror of
https://github.com/YosysHQ/yosys
synced 2025-12-15 00:38:59 +00:00
Merge pull request #5496 from YosysHQ/emil/liberty-flop-loops
read_liberty: support loopy retention cells
This commit is contained in:
commit
9871e9b17e
10 changed files with 415 additions and 99 deletions
|
|
@ -5,8 +5,9 @@ module dff (D, CLK, Q);
|
|||
output Q;
|
||||
assign Q = IQ; // IQ
|
||||
always @(posedge CLK) begin
|
||||
// "(D)"
|
||||
IQ <= D;
|
||||
end
|
||||
always @(posedge CLK) begin
|
||||
IQN <= ~(D);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ module imux2 (A, B, S, Y);
|
|||
endmodule
|
||||
module dff (D, CLK, RESET, PRESET, Q, QN);
|
||||
reg IQ, IQN;
|
||||
wire IQ_clear, IQ_preset;
|
||||
input D;
|
||||
input CLK;
|
||||
input RESET;
|
||||
|
|
@ -49,25 +50,30 @@ module dff (D, CLK, RESET, PRESET, Q, QN);
|
|||
assign Q = IQ; // "IQ"
|
||||
output QN;
|
||||
assign QN = IQN; // "IQN"
|
||||
always @(posedge CLK, posedge RESET, posedge PRESET) begin
|
||||
if ((RESET) && (PRESET)) begin
|
||||
always @(posedge CLK, posedge IQ_clear, posedge IQ_preset) begin
|
||||
if (IQ_clear) begin
|
||||
IQ <= 0;
|
||||
IQN <= 0;
|
||||
end
|
||||
else if (RESET) begin
|
||||
IQ <= 0;
|
||||
IQN <= 1;
|
||||
end
|
||||
else if (PRESET) begin
|
||||
else if (IQ_preset) begin
|
||||
IQ <= 1;
|
||||
IQN <= 0;
|
||||
end
|
||||
else begin
|
||||
// "D"
|
||||
IQ <= D;
|
||||
end
|
||||
end
|
||||
always @(posedge CLK, posedge IQ_clear, posedge IQ_preset) begin
|
||||
if (IQ_preset) begin
|
||||
IQN <= 0;
|
||||
end
|
||||
else if (IQ_clear) begin
|
||||
IQN <= 1;
|
||||
end
|
||||
else begin
|
||||
IQN <= ~(D);
|
||||
end
|
||||
end
|
||||
assign IQ_clear = RESET;
|
||||
assign IQ_preset = PRESET;
|
||||
endmodule
|
||||
module latch (D, G, Q, QN);
|
||||
reg IQ, IQN;
|
||||
|
|
|
|||
9
tests/liberty/read_liberty.ys
Normal file
9
tests/liberty/read_liberty.ys
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
read_liberty retention.lib
|
||||
rename retention_cell retention_cell_lib
|
||||
read_verilog retention.lib.verilogsim
|
||||
proc
|
||||
rename retention_cell retention_cell_vlog
|
||||
async2sync
|
||||
equiv_make retention_cell_lib retention_cell_vlog equiv
|
||||
equiv_induct equiv
|
||||
equiv_status -assert equiv
|
||||
57
tests/liberty/retention.lib
Normal file
57
tests/liberty/retention.lib
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
library (retention) {
|
||||
delay_model : table_lookup;
|
||||
voltage_unit : 1V;
|
||||
current_unit : 1mA;
|
||||
leakage_power_unit : 1nW;
|
||||
time_unit : 1ns;
|
||||
capacitive_load_unit (1, pf);
|
||||
pulling_resistance_unit : 1kohm;
|
||||
input_threshold_pct_rise : 50;
|
||||
input_threshold_pct_fall : 50;
|
||||
output_threshold_pct_rise : 50;
|
||||
output_threshold_pct_fall : 50;
|
||||
slew_lower_threshold_pct_rise : 30;
|
||||
slew_upper_threshold_pct_rise : 70;
|
||||
slew_upper_threshold_pct_fall : 70;
|
||||
slew_lower_threshold_pct_fall : 30;
|
||||
cell ("retention_cell") {
|
||||
ff (Q1,QN1) {
|
||||
clocked_on : "CK";
|
||||
next_state : "(D * !SE + SI * SE)";
|
||||
clear : "(((!B2B) * !Q2) + !RD)";
|
||||
preset : "((!B2B) * Q2)";
|
||||
clear_preset_var1 : "L";
|
||||
clear_preset_var2 : "H";
|
||||
}
|
||||
latch (Q2,QN2) {
|
||||
enable : "B1";
|
||||
data_in : "Q1";
|
||||
}
|
||||
pin (B1) {
|
||||
direction : input;
|
||||
}
|
||||
pin (B2B) {
|
||||
direction : input;
|
||||
}
|
||||
pin (CK) {
|
||||
clock : true;
|
||||
direction : input;
|
||||
}
|
||||
pin (D) {
|
||||
direction : input;
|
||||
}
|
||||
pin (Q) {
|
||||
direction : output;
|
||||
function : "Q1";
|
||||
}
|
||||
pin (RD) {
|
||||
direction : input;
|
||||
}
|
||||
pin (SE) {
|
||||
direction : input;
|
||||
}
|
||||
pin (SI) {
|
||||
direction : input;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
tests/liberty/retention.lib.filtered.ok
Normal file
42
tests/liberty/retention.lib.filtered.ok
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
library(retention) {
|
||||
cell("retention_cell") {
|
||||
ff(Q1, QN1) {
|
||||
clocked_on : "CK" ;
|
||||
next_state : "(D * !SE + SI * SE)" ;
|
||||
clear : "(((!B2B) * !Q2) + !RD)" ;
|
||||
preset : "((!B2B) * Q2)" ;
|
||||
clear_preset_var1 : "L" ;
|
||||
clear_preset_var2 : "H" ;
|
||||
}
|
||||
latch(Q2, QN2) {
|
||||
enable : "B1" ;
|
||||
data_in : "Q1" ;
|
||||
}
|
||||
pin(B1) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(B2B) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(CK) {
|
||||
clock : true ;
|
||||
direction : input ;
|
||||
}
|
||||
pin(D) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Q) {
|
||||
direction : output ;
|
||||
function : "Q1" ;
|
||||
}
|
||||
pin(RD) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(SE) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(SI) {
|
||||
direction : input ;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
tests/liberty/retention.lib.verilogsim.ok
Normal file
44
tests/liberty/retention.lib.verilogsim.ok
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
module retention_cell (B1, B2B, CK, D, Q, RD, SE, SI);
|
||||
reg Q1, QN1;
|
||||
wire Q1_clear, Q1_preset;
|
||||
reg Q2, QN2;
|
||||
input B1;
|
||||
input B2B;
|
||||
input CK;
|
||||
input D;
|
||||
output Q;
|
||||
assign Q = Q1; // "Q1"
|
||||
input RD;
|
||||
input SE;
|
||||
input SI;
|
||||
always @(posedge CK, posedge Q1_clear, posedge Q1_preset) begin
|
||||
if (Q1_clear) begin
|
||||
Q1 <= 0;
|
||||
end
|
||||
else if (Q1_preset) begin
|
||||
Q1 <= 1;
|
||||
end
|
||||
else begin
|
||||
Q1 <= ((D&(~SE))|(SI&SE));
|
||||
end
|
||||
end
|
||||
always @(posedge CK, posedge Q1_clear, posedge Q1_preset) begin
|
||||
if (Q1_clear) begin
|
||||
QN1 <= 1;
|
||||
end
|
||||
else if (Q1_preset) begin
|
||||
QN1 <= 0;
|
||||
end
|
||||
else begin
|
||||
QN1 <= ~(((D&(~SE))|(SI&SE)));
|
||||
end
|
||||
end
|
||||
assign Q1_clear = (((~B2B)&(~Q2))|(~RD));
|
||||
assign Q1_preset = ((~B2B)&Q2);
|
||||
always @* begin
|
||||
if (B1) begin
|
||||
Q2 <= Q1;
|
||||
QN2 <= ~(Q1);
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -4,8 +4,9 @@ module DFF (D, CK, Q);
|
|||
input CK;
|
||||
output Q;
|
||||
always @(posedge CK) begin
|
||||
// "D"
|
||||
IQ <= D;
|
||||
end
|
||||
always @(posedge CK) begin
|
||||
IQN <= ~(D);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ module dff1 (D, CLK, Q);
|
|||
output Q;
|
||||
assign Q = IQ; // IQ
|
||||
always @(posedge CLK) begin
|
||||
// !D
|
||||
IQ <= (~D);
|
||||
end
|
||||
always @(posedge CLK) begin
|
||||
IQN <= ~((~D));
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -17,8 +18,9 @@ module dff2 (D, CLK, Q);
|
|||
output Q;
|
||||
assign Q = IQ; // "IQ"
|
||||
always @(posedge CLK) begin
|
||||
// D '
|
||||
IQ <= (~D);
|
||||
end
|
||||
always @(posedge CLK) begin
|
||||
IQN <= ~((~D));
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -32,8 +34,9 @@ module dffe (D, EN, CLK, Q, QN);
|
|||
output QN;
|
||||
assign QN = IQN; // "IQN"
|
||||
always @(negedge CLK) begin
|
||||
// ( D & EN ) | ( IQ & ! EN )
|
||||
IQ <= ((D&EN)|(IQ&(~EN)));
|
||||
end
|
||||
always @(negedge CLK) begin
|
||||
IQN <= ~(((D&EN)|(IQ&(~EN))));
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue