diff options
author | Eddie Hung <eddie@fpgeh.com> | 2020-03-04 13:37:09 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-04 13:37:09 -0800 |
commit | 6eb528277e73a978ace7d6f693215d9ff92f898d (patch) | |
tree | f4e882e5504bda5674266fe54a37daab15b92519 /techlibs | |
parent | 0ec971444b0ae226417ac36d408569374269e799 (diff) | |
parent | 7b543fdb0cbd45dcf2d3322518cc02a01cc1e43f (diff) | |
download | yosys-6eb528277e73a978ace7d6f693215d9ff92f898d.tar.gz yosys-6eb528277e73a978ace7d6f693215d9ff92f898d.tar.bz2 yosys-6eb528277e73a978ace7d6f693215d9ff92f898d.zip |
Merge pull request #1735 from YosysHQ/eddie/abc9_dsp48e1
xilinx: cleanup DSP48E1 handling for abc9
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/xilinx/abc9_map.v | 43 | ||||
-rw-r--r-- | techlibs/xilinx/abc9_model.v | 149 | ||||
-rw-r--r-- | techlibs/xilinx/abc9_unmap.v | 13 | ||||
-rw-r--r-- | techlibs/xilinx/cells_sim.v | 148 |
4 files changed, 244 insertions, 109 deletions
diff --git a/techlibs/xilinx/abc9_map.v b/techlibs/xilinx/abc9_map.v index 53d9a3c9a..81f8a1d42 100644 --- a/techlibs/xilinx/abc9_map.v +++ b/techlibs/xilinx/abc9_map.v @@ -771,35 +771,16 @@ module DSP48E1 ( .RSTM(RSTM), .RSTP(RSTP) ); - - generate - wire [29:0] $A; - wire [17:0] $B; - wire [47:0] $C; - wire [24:0] $D; - - if (PREG == 0) begin - if (MREG == 0 && AREG == 0) assign $A = A; - else assign $A = 30'bx; - if (MREG == 0 && BREG == 0) assign $B = B; - else assign $B = 18'bx; - if (MREG == 0 && DREG == 0) assign $D = D; - else assign $D = 25'bx; - - if (CREG == 0) assign $C = C; - else assign $C = 48'bx; - end - else begin - assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx; - end - - if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") - $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") - $__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") - $__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); - else - $error("Invalid DSP48E1 configuration"); - endgenerate + $__ABC9_DSP48E1 #( + .ADREG(ADREG), + .AREG(AREG), + .BREG(BREG), + .CREG(CREG), + .DREG(DREG), + .MREG(MREG), + .PREG(PREG), + .USE_DPORT(USE_DPORT), + .USE_MULT(USE_MULT) + ) dsp_comb ( + .$A(A), .$B(B), .$C(C), .$D(D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT)); endmodule diff --git a/techlibs/xilinx/abc9_model.v b/techlibs/xilinx/abc9_model.v index f83e97a2a..2d109ef8a 100644 --- a/techlibs/xilinx/abc9_model.v +++ b/techlibs/xilinx/abc9_model.v @@ -94,10 +94,9 @@ module \$__ABC9_RAM7 (input A, input [6:0] S, output Y); endspecify endmodule -// Boxes used to represent the comb behaviour of various modes -// of DSP48E1 -`define ABC9_DSP48E1(__NAME__) """ -module __NAME__ ( +// Boxes used to represent the comb behaviour of DSP48E1 +(* abc9_box *) +module $__ABC9_DSP48E1 ( input [29:0] $A, input [17:0] $B, input [47:0] $C, @@ -106,44 +105,106 @@ module __NAME__ ( input [47:0] $PCIN, input [47:0] $PCOUT, output [47:0] P, - output [47:0] PCOUT); -""" -(* abc9_box *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT) - specify - ($A *> P) = 2823; - ($B *> P) = 2690; - ($C *> P) = 1325; - ($P *> P) = 0; - ($A *> PCOUT) = 2970; - ($B *> PCOUT) = 2838; - ($C *> PCOUT) = 1474; - ($PCOUT *> PCOUT) = 0; - endspecify -endmodule -(* abc9_box *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT_DPORT) - specify - ($A *> P) = 3806; - ($B *> P) = 2690; - ($C *> P) = 1325; - ($D *> P) = 3700; - ($P *> P) = 0; - ($A *> PCOUT) = 3954; - ($B *> PCOUT) = 2838; - ($C *> PCOUT) = 1474; - ($D *> PCOUT) = 3700; - ($PCOUT *> PCOUT) = 0; - endspecify -endmodule -(* abc9_box *) `ABC9_DSP48E1($__ABC9_DSP48E1) - specify - ($A *> P) = 1523; - ($B *> P) = 1509; - ($C *> P) = 1325; - ($P *> P) = 0; - ($A *> PCOUT) = 1671; - ($B *> PCOUT) = 1658; - ($C *> PCOUT) = 1474; - ($PCOUT *> PCOUT) = 0; - endspecify + output [47:0] PCOUT +); + parameter integer ADREG = 1; + parameter integer AREG = 1; + parameter integer BREG = 1; + parameter integer CREG = 1; + parameter integer DREG = 1; + parameter integer MREG = 1; + parameter integer PREG = 1; + parameter USE_DPORT = "FALSE"; + parameter USE_MULT = "MULTIPLY"; + + function integer \A.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.P.comb = 2823; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.P.comb = 3806; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.P.comb = 1523; + end + endfunction + function integer \A.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.PCOUT.comb = 2970; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.PCOUT.comb = 3954; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.PCOUT.comb = 1671; + end + endfunction + function integer \B.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.P.comb = 2690; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.P.comb = 2690; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.P.comb = 1509; + end + endfunction + function integer \B.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.PCOUT.comb = 2838; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.PCOUT.comb = 2838; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.PCOUT.comb = 1658; + end + endfunction + function integer \C.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.P.comb = 1325; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.P.comb = 1325; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.P.comb = 1325; + end + endfunction + function integer \C.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.PCOUT.comb = 1474; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474; + end + endfunction + function integer \D.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.P.comb = 3717; + end + endfunction + function integer \D.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.PCOUT.comb = 3700; + end + endfunction + + specify + ($P *> P) = 0; + ($PCOUT *> PCOUT) = 0; + endspecify + + // Identical comb delays to DSP48E1 in cells_sim.v + generate + if (PREG == 0 && MREG == 0 && AREG == 0 && ADREG == 0) + specify + ($A *> P) = \A.P.comb (); + ($A *> PCOUT) = \A.PCOUT.comb (); + endspecify + + if (PREG == 0 && MREG == 0 && BREG == 0) + specify + ($B *> P) = \B.P.comb (); + ($B *> PCOUT) = \B.PCOUT.comb (); + endspecify + + if (PREG == 0 && CREG == 0) + specify + ($C *> P) = \C.P.comb (); + ($C *> PCOUT) = \C.PCOUT.comb (); + endspecify + + if (PREG == 0 && MREG == 0 && ADREG == 0 && DREG == 0) + specify + ($D *> P) = \D.P.comb (); + ($D *> PCOUT) = \D.PCOUT.comb (); + endspecify + + if (PREG == 0) + specify + ($PCIN *> P) = 1107; + ($PCIN *> PCOUT) = 1255; + endspecify + endgenerate endmodule -`undef ABC9_DSP48E1 diff --git a/techlibs/xilinx/abc9_unmap.v b/techlibs/xilinx/abc9_unmap.v index c02cc196a..5604ceb0a 100644 --- a/techlibs/xilinx/abc9_unmap.v +++ b/techlibs/xilinx/abc9_unmap.v @@ -36,8 +36,7 @@ module $__ABC9_RAM7(input A, input [6:0] S, output Y); assign Y = A; endmodule -(* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *) -module $ABC9_DSP48E1( +module $__ABC9_DSP48E1( input [29:0] $A, input [17:0] $B, input [47:0] $C, @@ -48,5 +47,15 @@ module $ABC9_DSP48E1( output [47:0] P, output [47:0] PCOUT ); + parameter integer ADREG = 1; + parameter integer AREG = 1; + parameter integer BREG = 1; + parameter integer CREG = 1; + parameter integer DREG = 1; + parameter integer MREG = 1; + parameter integer PREG = 1; + parameter USE_DPORT = "FALSE"; + parameter USE_MULT = "MULTIPLY"; + assign P = $P, PCOUT = $PCOUT; endmodule diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index ed7ac2026..63223afbf 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -3063,7 +3063,6 @@ module DSP48E1 ( `ifdef YOSYS function integer \A.required ; begin - \A.required = 0; if (AREG != 0) \A.required = 254; else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin if (MREG != 0) \A.required = 1416; @@ -3083,7 +3082,6 @@ module DSP48E1 ( endfunction function integer \B.required ; begin - \B.required = 0; if (BREG != 0) \B.required = 324; else if (MREG != 0) \B.required = 1285; else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin @@ -3099,14 +3097,12 @@ module DSP48E1 ( endfunction function integer \C.required ; begin - \C.required = 0; if (CREG != 0) \C.required = 168; else if (PREG != 0) \C.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1534 : 1244) ; end endfunction function integer \D.required ; begin - \D.required = 0; if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin end else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin @@ -3119,15 +3115,8 @@ module DSP48E1 ( end end endfunction - function integer \PCIN.required ; - begin - \PCIN.required = 0; - if (PREG != 0) \PCIN.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025) ; - end - endfunction function integer \P.arrival ; begin - \P.arrival = 0; if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin if (PREG != 0) \P.arrival = 329; // Worst-case from CREG and MREG @@ -3155,13 +3144,10 @@ module DSP48E1 ( else if (AREG != 0) \P.arrival = 1632; else if (BREG != 0) \P.arrival = 1616; end - //else - // $error("Invalid DSP48E1 configuration"); end endfunction function integer \PCOUT.arrival ; begin - \PCOUT.arrival = 0; if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin if (PREG != 0) \PCOUT.arrival = 435; // Worst-case from CREG and MREG @@ -3189,27 +3175,125 @@ module DSP48E1 ( else if (AREG != 0) \PCOUT.arrival = 1780; else if (BREG != 0) \PCOUT.arrival = 1765; end - //else - // $error("Invalid DSP48E1 configuration"); + end + endfunction + function integer \A.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.P.comb = 2823; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.P.comb = 3806; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.P.comb = 1523; + end + endfunction + function integer \A.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.PCOUT.comb = 2970; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.PCOUT.comb = 3954; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.PCOUT.comb = 1671; + end + endfunction + function integer \B.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.P.comb = 2690; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.P.comb = 2690; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.P.comb = 1509; + end + endfunction + function integer \B.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.PCOUT.comb = 2838; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.PCOUT.comb = 2838; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.PCOUT.comb = 1658; + end + endfunction + function integer \C.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.P.comb = 1325; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.P.comb = 1325; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.P.comb = 1325; + end + endfunction + function integer \C.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474; + else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.PCOUT.comb = 1474; + else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474; + end + endfunction + function integer \D.P.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.P.comb = 3717; + end + endfunction + function integer \D.PCOUT.comb ; + begin + if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.PCOUT.comb = 3700; end endfunction - specify - $setup(A , posedge CLK &&& !IS_CLK_INVERTED, \A.required () ); - $setup(A , negedge CLK &&& IS_CLK_INVERTED, \A.required () ); - $setup(B , posedge CLK &&& !IS_CLK_INVERTED, \B.required () ); - $setup(B , negedge CLK &&& IS_CLK_INVERTED, \B.required () ); - $setup(C , posedge CLK &&& !IS_CLK_INVERTED, \C.required () ); - $setup(C , negedge CLK &&& IS_CLK_INVERTED, \C.required () ); - $setup(D , posedge CLK &&& !IS_CLK_INVERTED, \D.required () ); - $setup(D , negedge CLK &&& IS_CLK_INVERTED, \D.required () ); - $setup(PCIN, posedge CLK &&& !IS_CLK_INVERTED, \PCIN.required () ); - $setup(PCIN, negedge CLK &&& IS_CLK_INVERTED, \PCIN.required () ); - if (!IS_CLK_INVERTED && CEP) (posedge CLK => (P : 48'bx)) = \P.arrival () ; - if ( IS_CLK_INVERTED && CEP) (negedge CLK => (P : 48'bx)) = \P.arrival () ; - if (!IS_CLK_INVERTED && CEP) (posedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ; - if ( IS_CLK_INVERTED && CEP) (negedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ; - endspecify + generate + if (PREG == 0 && MREG == 0 && AREG == 0 && ADREG == 0) + specify + (A *> P) = \A.P.comb (); + (A *> PCOUT) = \A.PCOUT.comb (); + endspecify + else + specify + $setup(A, posedge CLK &&& !IS_CLK_INVERTED, \A.required () ); + $setup(A, negedge CLK &&& IS_CLK_INVERTED, \A.required () ); + endspecify + + if (PREG == 0 && MREG == 0 && BREG == 0) + specify + (B *> P) = \B.P.comb (); + (B *> PCOUT) = \B.PCOUT.comb (); + endspecify + else + specify + $setup(B, posedge CLK &&& !IS_CLK_INVERTED, \B.required () ); + $setup(B, negedge CLK &&& IS_CLK_INVERTED, \B.required () ); + endspecify + + if (PREG == 0 && CREG == 0) + specify + (C *> P) = \C.P.comb (); + (C *> PCOUT) = \C.PCOUT.comb (); + endspecify + else + specify + $setup(C, posedge CLK &&& !IS_CLK_INVERTED, \C.required () ); + $setup(C, negedge CLK &&& IS_CLK_INVERTED, \C.required () ); + endspecify + + if (PREG == 0 && MREG == 0 && ADREG == 0 && DREG == 0) + specify + (D *> P) = \D.P.comb (); + (D *> PCOUT) = \D.PCOUT.comb (); + endspecify + else + specify + $setup(D, posedge CLK &&& !IS_CLK_INVERTED, \D.required () ); + $setup(D, negedge CLK &&& IS_CLK_INVERTED, \D.required () ); + endspecify + + if (PREG == 0) + specify + (PCIN *> P) = 1107; + (PCIN *> PCOUT) = 1255; + endspecify + else + specify + $setup(PCIN, posedge CLK &&& !IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025); + $setup(PCIN, negedge CLK &&& IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025); + endspecify + + if (PREG || AREG || ADREG || BREG || CREG || DREG || MREG) + specify + if (!IS_CLK_INVERTED && CEP) (posedge CLK => (P : 48'bx)) = \P.arrival () ; + if ( IS_CLK_INVERTED && CEP) (negedge CLK => (P : 48'bx)) = \P.arrival () ; + if (!IS_CLK_INVERTED && CEP) (posedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ; + if ( IS_CLK_INVERTED && CEP) (negedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ; + endspecify + endgenerate `endif initial begin |