mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
abc9_ops: add 'dff' label for auto handling of (* abc9_flop *) boxes
This commit is contained in:
parent
accfc70fc2
commit
95763c8d18
9 changed files with 403 additions and 640 deletions
|
@ -1,6 +1,3 @@
|
|||
module \$__ABC9_FF_ (input D, output Q);
|
||||
endmodule
|
||||
|
||||
(* abc9_box *)
|
||||
module \$__ABC9_DELAY (input I, output O);
|
||||
parameter DELAY = 0;
|
||||
|
|
|
@ -22,360 +22,6 @@
|
|||
// before invoking the `abc9` pass in order to transform the design into
|
||||
// a format that it understands.
|
||||
|
||||
`ifdef DFF_MODE
|
||||
// For example, (complex) flip-flops are expected to be described as an
|
||||
// combinatorial box (containing all control logic such as clock enable
|
||||
// or synchronous resets) followed by a basic D-Q flop.
|
||||
// Yosys will automatically analyse the simulation model (described in
|
||||
// cells_sim.v) and detach any $_DFF_P_ or $_DFF_N_ cells present in
|
||||
// order to extract the combinatorial control logic left behind.
|
||||
// Specifically, a simulation model similar to the one below:
|
||||
//
|
||||
// ++===================================++
|
||||
// || Sim model ||
|
||||
// || /\/\/\/\ ||
|
||||
// D -->>-----< > +------+ ||
|
||||
// R -->>-----< Comb. > |$_DFF_| ||
|
||||
// CE -->>-----< logic >-----| [NP]_|---+---->>-- Q
|
||||
// || +--< > +------+ | ||
|
||||
// || | \/\/\/\/ | ||
|
||||
// || | | ||
|
||||
// || +----------------------------+ ||
|
||||
// || ||
|
||||
// ++===================================++
|
||||
//
|
||||
// is transformed into:
|
||||
//
|
||||
// ++==================++
|
||||
// || Comb box ||
|
||||
// || ||
|
||||
// || /\/\/\/\ ||
|
||||
// D -->>-----< > ||
|
||||
// R -->>-----< Comb. > || +-----------+
|
||||
// CE -->>-----< logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q
|
||||
// abc9_ff.Q +-->>-----< > || +-----------+ |
|
||||
// | || \/\/\/\/ || |
|
||||
// | || || |
|
||||
// | ++==================++ |
|
||||
// | |
|
||||
// +-----------------------------------------------+
|
||||
//
|
||||
// The purpose of the following FD* rules are to wrap the flop with:
|
||||
// (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
|
||||
// the connectivity of its basic D-Q flop
|
||||
// (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
|
||||
// capture asynchronous behaviour
|
||||
// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
|
||||
// (indicated to `abc9' so that it only performs sequential synthesis
|
||||
// (with reachability analysis) correctly on one domain at a time)
|
||||
// (d) an (* abc9_init *) attribute on the $__ABC9_FF_ cell capturing its
|
||||
// initial state
|
||||
// NOTE: in order to perform sequential synthesis, `abc9' requires that
|
||||
// the initial value of all flops be zero
|
||||
// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
|
||||
// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
|
||||
|
||||
module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_R_INVERTED = 1'b0;
|
||||
wire QQ, $Q;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDSE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_S_INVERTED(IS_R_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDRE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_R_INVERTED(IS_R_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .R(R)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
||||
endmodule
|
||||
module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
wire QQ, $Q;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDSE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDRE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .R(R)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
||||
endmodule
|
||||
|
||||
module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_S_INVERTED = 1'b0;
|
||||
wire QQ, $Q;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDRE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_R_INVERTED(IS_S_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDSE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_S_INVERTED(IS_S_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
|
||||
);
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
||||
endmodule
|
||||
module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
wire QQ, $Q;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDRE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDSE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
|
||||
);
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
|
||||
endmodule
|
||||
|
||||
module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_CLR_INVERTED = 1'b0;
|
||||
wire QQ, $Q, $QQ;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDPE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_PRE_INVERTED(IS_CLR_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC1 below
|
||||
);
|
||||
// Since this is an async flop, async behaviour is dealt with here
|
||||
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDCE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_CLR_INVERTED(IS_CLR_INVERTED)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC0 below
|
||||
);
|
||||
// Since this is an async flop, async behaviour is dealt with here
|
||||
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
||||
endmodule
|
||||
module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
wire QQ, $Q, $QQ;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDPE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC1 below
|
||||
);
|
||||
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDCE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC0 below
|
||||
);
|
||||
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
||||
endmodule
|
||||
|
||||
module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_PRE_INVERTED = 1'b0;
|
||||
wire QQ, $Q, $QQ;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDCE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_CLR_INVERTED(IS_PRE_INVERTED),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC0 below
|
||||
);
|
||||
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDPE #(
|
||||
.INIT(1'b0),
|
||||
.IS_C_INVERTED(IS_C_INVERTED),
|
||||
.IS_D_INVERTED(IS_D_INVERTED),
|
||||
.IS_PRE_INVERTED(IS_PRE_INVERTED),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC1 below
|
||||
);
|
||||
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
||||
endmodule
|
||||
module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
wire QQ, $Q, $QQ;
|
||||
generate if (INIT == 1'b1) begin
|
||||
assign Q = ~QQ;
|
||||
FDCE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC0 below
|
||||
);
|
||||
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
|
||||
end
|
||||
else begin
|
||||
assign Q = QQ;
|
||||
FDPE_1 #(
|
||||
.INIT(1'b0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
|
||||
// ^^^ Note that async
|
||||
// control is not directly
|
||||
// supported by abc9 but its
|
||||
// behaviour is captured by
|
||||
// $__ABC9_ASYNC1 below
|
||||
);
|
||||
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
|
||||
end endgenerate
|
||||
(* abc9_init = 1'b0 *)
|
||||
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
|
||||
|
||||
// Special signals
|
||||
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
|
||||
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
// Attach a (combinatorial) black-box onto the output
|
||||
// of thes LUTRAM primitives to capture their
|
||||
// asynchronous read behaviour
|
||||
|
|
|
@ -25,10 +25,6 @@ module $__ABC9_ASYNC01(input A, S, output Y);
|
|||
assign Y = A;
|
||||
endmodule
|
||||
|
||||
module $__ABC9_FF_(input D, output Q);
|
||||
assign Q = D;
|
||||
endmodule
|
||||
|
||||
module $__ABC9_RAM6(input A, input [5:0] S, output Y);
|
||||
assign Y = A;
|
||||
endmodule
|
||||
|
|
|
@ -640,7 +640,7 @@ module FDRSE (
|
|||
Q <= d;
|
||||
endmodule
|
||||
|
||||
(* abc9_flop, lib_whitebox *)
|
||||
(* lib_whitebox *)
|
||||
module FDCE (
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
|
@ -683,7 +683,7 @@ module FDCE (
|
|||
endspecify
|
||||
endmodule
|
||||
|
||||
(* abc9_flop, lib_whitebox *)
|
||||
(* lib_whitebox *)
|
||||
module FDCE_1 (
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
|
@ -708,7 +708,7 @@ module FDCE_1 (
|
|||
endspecify
|
||||
endmodule
|
||||
|
||||
(* abc9_flop, lib_whitebox *)
|
||||
(* lib_whitebox *)
|
||||
module FDPE (
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
|
@ -750,7 +750,7 @@ module FDPE (
|
|||
endspecify
|
||||
endmodule
|
||||
|
||||
(* abc9_flop, lib_whitebox *)
|
||||
(* lib_whitebox *)
|
||||
module FDPE_1 (
|
||||
output reg Q,
|
||||
(* clkbuf_sink *)
|
||||
|
|
|
@ -613,10 +613,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
if (family != "xc7")
|
||||
log_warning("'synth_xilinx -abc9' not currently supported for the '%s' family, "
|
||||
"will use timing for 'xc7' instead.\n", family.c_str());
|
||||
std::string techmap_args = "-map +/xilinx/abc9_map.v -max_iter 1";
|
||||
if (dff_mode)
|
||||
techmap_args += " -D DFF_MODE";
|
||||
run("techmap " + techmap_args);
|
||||
run("techmap -map +/xilinx/abc9_map.v -max_iter 1");
|
||||
run("read_verilog -icells -lib -specify +/abc9_model.v +/xilinx/abc9_model.v");
|
||||
std::string abc9_opts;
|
||||
std::string k = "synth_xilinx.abc9.W";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue