From 5d5029fa75b8cb37c07fc15a0429e28fe317b472 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Apr 2020 07:31:07 -0700 Subject: ecp5: replace ecp5_ffinit with techmap rules + dff2dffs -match-init --- techlibs/ecp5/Makefile.inc | 3 +- techlibs/ecp5/cells_map.v | 278 ++++++++++++++++++++++++++++++++++---------- techlibs/ecp5/synth_ecp5.cc | 3 +- 3 files changed, 220 insertions(+), 64 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 217151e96..6bc9c854e 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,6 +1,5 @@ -OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \ - techlibs/ecp5/ecp5_gsr.o +OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o GENFILES += techlibs/ecp5/bram_init_1_2_4.vh GENFILES += techlibs/ecp5/bram_init_9_18_36.vh diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index c031703a9..f8df08eab 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -1,65 +1,223 @@ -module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - -module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule - -module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule - -module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule -module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +(* techmap_celltype = "$_DFF_N_ $_DFF_P_" *) +module \$_DFF_x_ (input D, C, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + localparam REGSET = "SET"; + else + localparam REGSET = "RESET"; + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET)) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); +endmodule + +(* techmap_celltype = "$_DFFE_NN_ $_DFFE_PN_ $_DFFE_NP_ $_DFFE_PP_" *) +module \$_DFFE_xx_ (input D, C, E, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") + localparam CEMUX = "INV"; + else + localparam CEMUX = "CE"; + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + localparam REGSET = "SET"; + else + localparam REGSET = "RESET"; + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET)) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); +endmodule + +(* techmap_celltype = "$_DFF_NN0_ $_DFF_NN1_ $_DFF_PN0_ $_DFF_PN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PP0_ $_DFF_PP1_" *) +module \$_DFF_xxx_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + // TODO: Why not use LSRMUX param? + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + wire LSR_ = !R; + else + wire LSR_ = R; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin + localparam REGSET = "SET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("ECP5 doesn't support FFs with asynchronous set initialized to 0"); + end + else begin + localparam REGSET = "RESET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("ECP5 doesn't support FFs with asynchronous reset initialized to 1"); + end + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(LSR_), .DI(D), .Q(Q)); +endmodule + +(* techmap_celltype = "$__DFFS_NN0_ $__DFFS_NN1_ $__DFFS_PN0_ $__DFFS_PN1_ $__DFFS_NP0_ $__DFFS_NP1_ $__DFFS_PP0_ $__DFFS_PP1_" *) +module \$__DFFS_xxx_ (input D, C, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + // TODO: Why not use LSRMUX param? + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + wire LSR_ = !R; + else + wire LSR_ = R; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin + localparam REGSET = "SET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b0) + // init is 0, reset to 1 + wire D_ = D || LSR_; + else + wire D_ = D; + end + else begin + localparam REGSET = "RESET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + // init is 1, reset to 0 + wire D_ = !(D && LSR_); + else + wire D_ = D; + end + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(LSR_), .DI(D_), .Q(Q)); +endmodule + +(* techmap_celltype = "$__DFFE_NN0 $__DFFE_NN1 $__DFFE_PN0 $__DFFE_PN1 $__DFFE_NP0 $__DFFE_NP1 $__DFFE_PP0 $__DFFE_PP1" *) +module \$__DFFE_xxx_ (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + // TODO: Why not use LSRMUX param? + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + wire LSR_ = !R; + else + wire LSR_ = R; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin + if (_TECHMAP_WIREINIT_Q_ === 1'b0) + $error("ECP5 doesn't support FFs with asynchronous set initialized to 0"); + else + localparam REGSET = "SET"; + end + else begin + if (_TECHMAP_WIREINIT_Q_ === 1'b1) + $error("ECP5 doesn't support FFs with asynchronous reset initialized to 1"); + else + localparam REGSET = "RESET"; + end + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(LSR_), .DI(D), .Q(Q)); +endmodule + +(* techmap_celltype = "$__DFFSE_NN0 $__DFFSE_NN1 $__DFFSE_PN0 $__DFFSE_PN1 $__DFFSE_NP0 $__DFFSE_NP1 $__DFFSE_PP0 $__DFFSE_PP1" *) +module \$__DFFSE_xxx_ (input D, C, E, R, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + // TODO: Why not use LSRMUX param? + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + wire LSR_ = !R; + else + wire LSR_ = R; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin + localparam REGSET = "SET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b0) begin + // init is 0, reset to 1 + wire D_ = D || LSR_; + wire E_ = E || LSR_; + end + else begin + wire D_ = D; + wire E_ = E; + end + end + else begin + localparam REGSET = "RESET"; + if (_TECHMAP_WIREINIT_Q_ === 1'b1) begin + // init is 1, reset to 0 + wire D_ = !(D && LSR_); + wire E_ = !(E && LSR_); + end + else begin + wire D_ = D; + wire E_ = E; + end + end + endgenerate + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E_), .LSR(LSR_), .DI(D_), .Q(Q)); +endmodule `ifdef ASYNC_PRLD -module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule -module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule - -module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule -module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule - -module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule -module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule -module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule +(* techmap_celltype = "$_DLATCH_N_ $_DLATCH_P_" *) +module \$_DLATCH_x_ (input E, input D, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + // TODO: Why not use LSRMUX param? + if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") + wire LSR_ = !E; + else + wire LSR_ = E; + if (_TECHMAP_WIREINIT_Q_ !== 1'bx) + $error("ECP5 doesn't support latches with initial values"); // TODO: Check + endgenerate + TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(LSR_), .DI(1'b0), .M(D), .Q(Q)); +endmodule + +(* techmap_celltype = "$_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_PNN_ $_DFFSR_PNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PPN_ $_DFFSR_PPP_" *) +module \$_DFFSR_xxx_ (input C, S, R, D, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; + generate + if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") + localparam CLKMUX = "INV"; + else + localparam CLKMUX = "CLK"; + if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") + wire S_ = !S; + else + wire S_ = S; + if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") + wire R_ = !R; + else + wire R_ = R; + if (_TECHMAP_WIREINIT_Q_ !== 1'bx) + $error("ECP5 doesn't support FFs with asynchronous set and reset with initial values"); + endgenerate + + TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX(CLKINV), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S_ || R_), .DI(D), .M(!R_), .Q(Q)); +endmodule `endif `include "cells_ff.vh" diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index b9b236a0c..5f00d3d4e 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -303,14 +303,13 @@ struct SynthEcp5Pass : public ScriptPass if (check_label("map_ffs")) { - run("dff2dffs"); + run("dff2dffs -match-init"); run("opt_clean"); if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_ffinit"); run("ecp5_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); -- cgit v1.2.3 From 34c77326420e4f906544e26499683869c47d09aa Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Apr 2020 07:51:23 -0700 Subject: ecp5: add synth_ecp5 -dff to work with -abc9 --- techlibs/ecp5/cells_sim.v | 21 +++++++++++++++++++++ techlibs/ecp5/synth_ecp5.cc | 38 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 12 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 12b33e925..69685683f 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -294,6 +294,7 @@ endmodule // --------------------------------------- +(* abc9_flop=(SRMODE != "ASYNC"), lib_whitebox=(SRMODE != "ASYNC") *) module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); parameter GSR = "ENABLED"; parameter [127:0] CEMUX = "1"; @@ -340,6 +341,26 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); Q <= DI; end endgenerate + + generate + // TODO + if (CLKMUX == "INV") + specify + $setup(DI, negedge CLK, 0); + $setup(CE, negedge CLK, 0); + $setup(LSR, negedge CLK, 0); + if (muxlsr) (negedge CLK => (Q : DI)) = 0; + if (!muxlsr && muxce) (negedge CLK => (Q : srval)) = 0; + endspecify + else + specify + $setup(DI, posedge CLK, 0); + $setup(CE, posedge CLK, 0); + $setup(LSR, posedge CLK, 0); + if (muxlsr) (posedge CLK => (Q : srval)) = 0; + if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0; + endspecify + endgenerate endmodule // --------------------------------------- diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 5f00d3d4e..ecc5039e6 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -66,6 +66,9 @@ struct SynthEcp5Pass : public ScriptPass log(" -noflatten\n"); log(" do not flatten design before synthesis\n"); log("\n"); + log(" -dff\n"); + log(" run 'abc'/'abc9' with -dff option\n"); + log("\n"); log(" -retime\n"); log(" run 'abc' with '-dff -D 1' options\n"); log("\n"); @@ -107,7 +110,7 @@ struct SynthEcp5Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, retime, abc2, abc9, nodsp, vpr; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr; void clear_flags() YS_OVERRIDE { @@ -122,6 +125,7 @@ struct SynthEcp5Pass : public ScriptPass nowidelut = false; asyncprld = false; flatten = true; + dff = false; retime = false; abc2 = false; vpr = false; @@ -169,6 +173,10 @@ struct SynthEcp5Pass : public ScriptPass flatten = false; continue; } + if (args[argidx] == "-dff") { + dff = true; + continue; + } if (args[argidx] == "-retime") { retime = true; continue; @@ -307,6 +315,8 @@ struct SynthEcp5Pass : public ScriptPass run("opt_clean"); if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); + if ((abc9 && dff) || help_mode) + run("zinit -all", "(-abc9 and -dff only)"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); @@ -323,7 +333,7 @@ struct SynthEcp5Pass : public ScriptPass std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v"; if (abc9) techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1"; - if (!asyncprld || abc9) + if (!techmap_args.empty()) run("techmap " + techmap_args); if (abc9) { @@ -337,26 +347,30 @@ struct SynthEcp5Pass : public ScriptPass else abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); if (nowidelut) - run("abc9 -maxlut 4 -W 200"); - else - run("abc9 -W 200"); + abc9_args += " -maxlut 4"; + if (dff) + abc9_args += " -dff"; + run("abc9" + abc9_args); run("techmap -map +/ecp5/abc9_unmap.v"); } else { + std::string abc_args = " -dress"; if (nowidelut) - run("abc -lut 4 -dress"); + abc_args += " -lut 4"; else - run("abc -lut 4:7 -dress"); + abc_args += " -lut 4:7"; + if (dff) + abc_args += " -dff"; + run("abc" + abc_args); } run("clean"); } if (check_label("map_cells")) { - if (vpr) - run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); - else - run("techmap -map +/ecp5/cells_map.v", "(with -D NO_LUT in vpr mode)"); - + if (help_mode) + run("techmap -map +/ecp5/cells_map.v", "(skip if -vpr)"); + else if (!vpr) + run("techmap -map +/ecp5/cells_map.v"); run("opt_lut_ins -tech ecp5"); run("clean"); } -- cgit v1.2.3 From a52f779ecae79be5ea79bd27f04837e7031f8415 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Apr 2020 10:36:07 -0700 Subject: ecp5: (* abc9_flop *) gated behind YOSYS --- techlibs/ecp5/cells_sim.v | 2 ++ 1 file changed, 2 insertions(+) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 69685683f..563592218 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -294,7 +294,9 @@ endmodule // --------------------------------------- +`ifdef YOSYS (* abc9_flop=(SRMODE != "ASYNC"), lib_whitebox=(SRMODE != "ASYNC") *) +`endif module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); parameter GSR = "ENABLED"; parameter [127:0] CEMUX = "1"; -- cgit v1.2.3 From 0d84ff3fc47fbc17184e706ea3ef1ee801f19790 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 14 Apr 2020 12:56:28 -0700 Subject: Revert "ecp5: replace ecp5_ffinit with techmap rules + dff2dffs -match-init" This reverts commit 8c702b6cc0221a00021a3e4661c883bb591c924b. --- techlibs/ecp5/Makefile.inc | 3 +- techlibs/ecp5/cells_map.v | 278 ++++++++++---------------------------------- techlibs/ecp5/synth_ecp5.cc | 3 +- 3 files changed, 64 insertions(+), 220 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 6bc9c854e..217151e96 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,5 +1,6 @@ -OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o +OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \ + techlibs/ecp5/ecp5_gsr.o GENFILES += techlibs/ecp5/bram_init_1_2_4.vh GENFILES += techlibs/ecp5/bram_init_9_18_36.vh diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index f8df08eab..c031703a9 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -1,223 +1,65 @@ -(* techmap_celltype = "$_DFF_N_ $_DFF_P_" *) -module \$_DFF_x_ (input D, C, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - localparam REGSET = "SET"; - else - localparam REGSET = "RESET"; - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET)) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); -endmodule - -(* techmap_celltype = "$_DFFE_NN_ $_DFFE_PN_ $_DFFE_NP_ $_DFFE_PP_" *) -module \$_DFFE_xx_ (input D, C, E, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") - localparam CEMUX = "INV"; - else - localparam CEMUX = "CE"; - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - localparam REGSET = "SET"; - else - localparam REGSET = "RESET"; - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET)) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); -endmodule - -(* techmap_celltype = "$_DFF_NN0_ $_DFF_NN1_ $_DFF_PN0_ $_DFF_PN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PP0_ $_DFF_PP1_" *) -module \$_DFF_xxx_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - // TODO: Why not use LSRMUX param? - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - wire LSR_ = !R; - else - wire LSR_ = R; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin - localparam REGSET = "SET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("ECP5 doesn't support FFs with asynchronous set initialized to 0"); - end - else begin - localparam REGSET = "RESET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("ECP5 doesn't support FFs with asynchronous reset initialized to 1"); - end - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(LSR_), .DI(D), .Q(Q)); -endmodule - -(* techmap_celltype = "$__DFFS_NN0_ $__DFFS_NN1_ $__DFFS_PN0_ $__DFFS_PN1_ $__DFFS_NP0_ $__DFFS_NP1_ $__DFFS_PP0_ $__DFFS_PP1_" *) -module \$__DFFS_xxx_ (input D, C, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - // TODO: Why not use LSRMUX param? - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - wire LSR_ = !R; - else - wire LSR_ = R; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin - localparam REGSET = "SET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b0) - // init is 0, reset to 1 - wire D_ = D || LSR_; - else - wire D_ = D; - end - else begin - localparam REGSET = "RESET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - // init is 1, reset to 0 - wire D_ = !(D && LSR_); - else - wire D_ = D; - end - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(LSR_), .DI(D_), .Q(Q)); -endmodule - -(* techmap_celltype = "$__DFFE_NN0 $__DFFE_NN1 $__DFFE_PN0 $__DFFE_PN1 $__DFFE_NP0 $__DFFE_NP1 $__DFFE_PP0 $__DFFE_PP1" *) -module \$__DFFE_xxx_ (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - // TODO: Why not use LSRMUX param? - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - wire LSR_ = !R; - else - wire LSR_ = R; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin - if (_TECHMAP_WIREINIT_Q_ === 1'b0) - $error("ECP5 doesn't support FFs with asynchronous set initialized to 0"); - else - localparam REGSET = "SET"; - end - else begin - if (_TECHMAP_WIREINIT_Q_ === 1'b1) - $error("ECP5 doesn't support FFs with asynchronous reset initialized to 1"); - else - localparam REGSET = "RESET"; - end - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(LSR_), .DI(D), .Q(Q)); -endmodule - -(* techmap_celltype = "$__DFFSE_NN0 $__DFFSE_NN1 $__DFFSE_PN0 $__DFFSE_PN1 $__DFFSE_NP0 $__DFFSE_NP1 $__DFFSE_PP0 $__DFFSE_PP1" *) -module \$__DFFSE_xxx_ (input D, C, E, R, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - // TODO: Why not use LSRMUX param? - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - wire LSR_ = !R; - else - wire LSR_ = R; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "1") begin - localparam REGSET = "SET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b0) begin - // init is 0, reset to 1 - wire D_ = D || LSR_; - wire E_ = E || LSR_; - end - else begin - wire D_ = D; - wire E_ = E; - end - end - else begin - localparam REGSET = "RESET"; - if (_TECHMAP_WIREINIT_Q_ === 1'b1) begin - // init is 1, reset to 0 - wire D_ = !(D && LSR_); - wire E_ = !(E && LSR_); - end - else begin - wire D_ = D; - wire E_ = E; - end - end - endgenerate - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX(CLKMUX), .LSRMUX("LSR"), .REGSET(REGSET), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E_), .LSR(LSR_), .DI(D_), .Q(Q)); -endmodule +module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule +module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule +module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule + +module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule + +module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule + +module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule + +module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule + +module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule + +module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule + +module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule + +module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule `ifdef ASYNC_PRLD -(* techmap_celltype = "$_DLATCH_N_ $_DLATCH_P_" *) -module \$_DLATCH_x_ (input E, input D, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - // TODO: Why not use LSRMUX param? - if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") - wire LSR_ = !E; - else - wire LSR_ = E; - if (_TECHMAP_WIREINIT_Q_ !== 1'bx) - $error("ECP5 doesn't support latches with initial values"); // TODO: Check - endgenerate - TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(LSR_), .DI(1'b0), .M(D), .Q(Q)); -endmodule - -(* techmap_celltype = "$_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_PNN_ $_DFFSR_PNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PPN_ $_DFFSR_PPP_" *) -module \$_DFFSR_xxx_ (input C, S, R, D, output Q); - parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; - parameter _TECHMAP_CELLTYPE_ = ""; - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; - generate - if (_TECHMAP_CELLTYPE_[3*8+:8] == "N") - localparam CLKMUX = "INV"; - else - localparam CLKMUX = "CLK"; - if (_TECHMAP_CELLTYPE_[2*8+:8] == "N") - wire S_ = !S; - else - wire S_ = S; - if (_TECHMAP_CELLTYPE_[1*8+:8] == "N") - wire R_ = !R; - else - wire R_ = R; - if (_TECHMAP_WIREINIT_Q_ !== 1'bx) - $error("ECP5 doesn't support FFs with asynchronous set and reset with initial values"); - endgenerate - - TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX(CLKINV), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S_ || R_), .DI(D), .M(!R_), .Q(Q)); -endmodule +module \$_DLATCH_N_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(!E), .DI(1'b0), .M(D), .Q(Q)); endmodule +module \$_DLATCH_P_ (input E, input D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.LSR(E), .DI(1'b0), .M(D), .Q(Q)); endmodule + +module \$_DFFSR_NNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_NNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule +module \$_DFFSR_NPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_NPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule + +module \$_DFFSR_PNN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_PNP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!S || R), .DI(D), .M(!R), .Q(Q)); endmodule +module \$_DFFSR_PPN_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || !R), .DI(D), .M(R), .Q(Q)); endmodule +module \$_DFFSR_PPP_ (input C, S, R, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(S || R), .DI(D), .M(!R), .Q(Q)); endmodule `endif `include "cells_ff.vh" diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index ecc5039e6..8039531ae 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -311,7 +311,7 @@ struct SynthEcp5Pass : public ScriptPass if (check_label("map_ffs")) { - run("dff2dffs -match-init"); + run("dff2dffs"); run("opt_clean"); if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); @@ -320,6 +320,7 @@ struct SynthEcp5Pass : public ScriptPass run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); + run("ecp5_ffinit"); run("ecp5_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); -- cgit v1.2.3 From 8fbb55f4aba9ccb850680dc9c7ab582e8c964a4a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 16 Apr 2020 10:25:41 -0700 Subject: synth_*: no need to explicitly read +/abc9_model.v --- techlibs/ecp5/synth_ecp5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 8039531ae..c1545cbb5 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -338,7 +338,7 @@ struct SynthEcp5Pass : public ScriptPass run("techmap " + techmap_args); if (abc9) { - run("read_verilog -icells -lib -specify +/abc9_model.v +/ecp5/abc9_model.v"); + run("read_verilog -icells -lib -specify +/ecp5/abc9_model.v"); std::string abc9_opts; if (nowidelut) abc9_opts += " -maxlut 4"; -- cgit v1.2.3 From 7cd3f4a79bde6dbe2cd7f90d0a4996aebe70fd10 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Apr 2020 12:22:39 -0700 Subject: abc9_ops: add -prep_bypass for auto bypass boxes; refactor Eliminate need for abc9_{,un}map.v in xilinx -prep_dff_{hier,unmap} -> -prep_hier --- techlibs/ecp5/synth_ecp5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index c1545cbb5..3e475baab 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -316,7 +316,7 @@ struct SynthEcp5Pass : public ScriptPass if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); if ((abc9 && dff) || help_mode) - run("zinit -all", "(-abc9 and -dff only)"); + run("zinit -all t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); -- cgit v1.2.3 From a323881e152c0d51728f3df773ac2f326544b379 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Apr 2020 14:13:38 -0700 Subject: xilinx/ecp5/ice40: add (* abc9_flop *) to bypass-able cells --- techlibs/ecp5/cells_sim.v | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 563592218..6f37823e4 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -186,6 +186,7 @@ module PFUMX (input ALUT, BLUT, C0, output Z); endmodule // --------------------------------------- +(* abc9_box, lib_whitebox *) module TRELLIS_DPR16X4 ( input [3:0] DI, input [3:0] WAD, @@ -222,10 +223,16 @@ module TRELLIS_DPR16X4 ( mem[WAD] <= DI; assign DO = mem[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify endmodule // --------------------------------------- +(* abc9_box, lib_whitebox *) module DPR16X4C ( input [3:0] DI, input WCK, WRE, @@ -281,6 +288,10 @@ module DPR16X4C ( assign DO = ram[RAD]; + specify + // TODO + (RAD *> DO) = 0; + endspecify endmodule // --------------------------------------- @@ -295,7 +306,7 @@ endmodule // --------------------------------------- `ifdef YOSYS -(* abc9_flop=(SRMODE != "ASYNC"), lib_whitebox=(SRMODE != "ASYNC") *) +(* abc9_flop=(SRMODE != "ASYNC"), abc9_box=(SRMODE == "ASYNC"), lib_whitebox *) `endif module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); parameter GSR = "ENABLED"; @@ -351,15 +362,27 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); $setup(DI, negedge CLK, 0); $setup(CE, negedge CLK, 0); $setup(LSR, negedge CLK, 0); - if (muxlsr) (negedge CLK => (Q : DI)) = 0; - if (!muxlsr && muxce) (negedge CLK => (Q : srval)) = 0; +`ifndef YOSYS + if (muxlsr) (negedge CLK => (Q : srval)) = 0; +`else + if (muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif + if (!muxlsr && muxce) (negedge CLK => (Q : DI)) = 0; endspecify else specify $setup(DI, posedge CLK, 0); $setup(CE, posedge CLK, 0); $setup(LSR, posedge CLK, 0); +`ifndef YOSYS if (muxlsr) (posedge CLK => (Q : srval)) = 0; +`else + if (muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0; endspecify endgenerate -- cgit v1.2.3 From 6c34945371a0446159423b0d70f9f10dbc2c4d07 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Apr 2020 15:45:05 -0700 Subject: xilinx/ice40/ecp5: zinit requires selected wires, so select them all --- techlibs/ecp5/synth_ecp5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 3e475baab..0e49ef01a 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -316,7 +316,7 @@ struct SynthEcp5Pass : public ScriptPass if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); if ((abc9 && dff) || help_mode) - run("zinit -all t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff"); + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$__DFFS*", "(only if -abc9 and -dff"); run(stringf("techmap -D NO_LUT %s -map +/ecp5/cells_map.v", help_mode ? "[-D ASYNC_PRLD]" : (asyncprld ? "-D ASYNC_PRLD" : ""))); run("opt_expr -undriven -mux_undef"); run("simplemap"); -- cgit v1.2.3 From 8cda29137e0e1c19e1115211ee695681bc901030 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 21 Apr 2020 17:04:26 -0700 Subject: ecp5: TRELLIS_FF bypass path only in async mode --- techlibs/ecp5/cells_sim.v | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 6f37823e4..357fd9173 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -363,11 +363,11 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); $setup(CE, negedge CLK, 0); $setup(LSR, negedge CLK, 0); `ifndef YOSYS - if (muxlsr) (negedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr) (negedge CLK => (Q : srval)) = 0; `else - if (muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path - // but for facilitating a bypass box, let's pretend it's - // a simple path + if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path `endif if (!muxlsr && muxce) (negedge CLK => (Q : DI)) = 0; endspecify @@ -377,11 +377,11 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); $setup(CE, posedge CLK, 0); $setup(LSR, posedge CLK, 0); `ifndef YOSYS - if (muxlsr) (posedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr) (posedge CLK => (Q : srval)) = 0; `else - if (muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path - // but for facilitating a bypass box, let's pretend it's - // a simple path + if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path `endif if (!muxlsr && muxce) (posedge CLK => (Q : DI)) = 0; endspecify -- cgit v1.2.3 From 39759d5f0ec9bfc0db3dd718cb035596da7f9668 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 13 May 2020 14:12:06 -0700 Subject: ecp5: fix rebase mistake --- techlibs/ecp5/synth_ecp5.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 0e49ef01a..c13020cc1 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -348,10 +348,10 @@ struct SynthEcp5Pass : public ScriptPass else abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); if (nowidelut) - abc9_args += " -maxlut 4"; + abc9_opts += " -maxlut 4"; if (dff) - abc9_args += " -dff"; - run("abc9" + abc9_args); + abc9_opts += " -dff"; + run("abc9" + abc9_opts); run("techmap -map +/ecp5/abc9_unmap.v"); } else { std::string abc_args = " -dress"; -- cgit v1.2.3 From fdc340db8e93d5b50ef515a231f2fef18bdd8165 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 13 May 2020 14:16:42 -0700 Subject: ecp5: synth_ecp5 to no longer need +/ecp5/abc9_{,un}map.v --- techlibs/ecp5/Makefile.inc | 3 --- techlibs/ecp5/abc9_map.v | 27 --------------------------- techlibs/ecp5/abc9_unmap.v | 5 ----- techlibs/ecp5/synth_ecp5.cc | 11 +++-------- 4 files changed, 3 insertions(+), 43 deletions(-) delete mode 100644 techlibs/ecp5/abc9_map.v delete mode 100644 techlibs/ecp5/abc9_unmap.v (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index 217151e96..9a337b2b6 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -23,9 +23,6 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dsp_map.v)) - -$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_map.v)) -$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_unmap.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc9_model.v)) EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk diff --git a/techlibs/ecp5/abc9_map.v b/techlibs/ecp5/abc9_map.v deleted file mode 100644 index 113a35b91..000000000 --- a/techlibs/ecp5/abc9_map.v +++ /dev/null @@ -1,27 +0,0 @@ -// --------------------------------------- - -// Attach a (combinatorial) black-box onto the output -// of this LUTRAM primitive to capture its -// asynchronous read behaviour -module TRELLIS_DPR16X4 ( - (* techmap_autopurge *) input [3:0] DI, - (* techmap_autopurge *) input [3:0] WAD, - (* techmap_autopurge *) input WRE, - (* techmap_autopurge *) input WCK, - (* techmap_autopurge *) input [3:0] RAD, - output [3:0] DO -); - parameter WCKMUX = "WCK"; - parameter WREMUX = "WRE"; - parameter [63:0] INITVAL = 64'h0000000000000000; - wire [3:0] $DO; - - TRELLIS_DPR16X4 #( - .WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL) - ) _TECHMAP_REPLACE_ ( - .DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK), - .RAD(RAD), .DO($DO) - ); - - $__ABC9_DPR16X4_COMB do (.$DO($DO), .RAD(RAD), .DO(DO)); -endmodule diff --git a/techlibs/ecp5/abc9_unmap.v b/techlibs/ecp5/abc9_unmap.v deleted file mode 100644 index cbdffdaf1..000000000 --- a/techlibs/ecp5/abc9_unmap.v +++ /dev/null @@ -1,5 +0,0 @@ -// --------------------------------------- - -module \$__ABC9_DPR16X4_COMB (input [3:0] $DO, RAD, output [3:0] DO); - assign DO = $DO; -endmodule diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index c13020cc1..b99cbdf83 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -328,14 +328,10 @@ struct SynthEcp5Pass : public ScriptPass if (check_label("map_luts")) { - if (abc2 || help_mode) { + if (abc2 || help_mode) run("abc", " (only if -abc2)"); - } - std::string techmap_args = asyncprld ? "" : "-map +/ecp5/latches_map.v"; - if (abc9) - techmap_args += " -map +/ecp5/abc9_map.v -max_iter 1"; - if (!techmap_args.empty()) - run("techmap " + techmap_args); + if (asyncprld || help_mode) + run("techmap -map +/ecp5/latches_map.v", "(only if -asyncprld)"); if (abc9) { run("read_verilog -icells -lib -specify +/ecp5/abc9_model.v"); @@ -352,7 +348,6 @@ struct SynthEcp5Pass : public ScriptPass if (dff) abc9_opts += " -dff"; run("abc9" + abc9_opts); - run("techmap -map +/ecp5/abc9_unmap.v"); } else { std::string abc_args = " -dress"; if (nowidelut) -- cgit v1.2.3 From cea614f5aeb78446c663240103f94f10e71681e2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 13 May 2020 14:42:18 -0700 Subject: ecp5: latches_map.v if *not* -asyncprld --- techlibs/ecp5/synth_ecp5.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'techlibs/ecp5') diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index b99cbdf83..e5c1f7550 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -330,8 +330,8 @@ struct SynthEcp5Pass : public ScriptPass { if (abc2 || help_mode) run("abc", " (only if -abc2)"); - if (asyncprld || help_mode) - run("techmap -map +/ecp5/latches_map.v", "(only if -asyncprld)"); + if (!asyncprld || help_mode) + run("techmap -map +/ecp5/latches_map.v", "(skip if -asyncprld)"); if (abc9) { run("read_verilog -icells -lib -specify +/ecp5/abc9_model.v"); -- cgit v1.2.3