1// 2// Copyright 2015 Ettus Research, a National Instruments Company 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6 7`timescale 1 ps / 1 ps 8 9// 10// Implements acc=((a+d)*b)+c or acc=((a+d)*b)+acc' 11// 12 13module add_then_mac 14 #(parameter DEVICE = "VIRTEX6") 15 ( 16 // Output ports 17 output [47:0] acc, 18 19 // Input ports 20 input carryin, 21 input ce, 22 input clk, 23 input [17:0] b, 24 input load, 25 input [47:0] c, 26 input [17:0] a, 27 input [17:0] d, 28 input rst 29 ); 30 31 32 wire [24:0] a_in; 33 wire [24:0] d_in; 34 35 localparam AREG_IN = 1; 36 localparam BREG_IN = 1; 37 localparam MREG_IN = 1; 38 localparam PREG_IN = 1; 39 localparam A1REG_IN = 1; 40 localparam A0REG_IN = 0; 41 localparam B1REG_IN = 1; 42 localparam B0REG_IN = 1; 43 44 // Sign extend inputs 45 assign a_in = (a[17] == 1'b1) ? {7'hff, a} : {7'h00, a}; 46 assign d_in = (d[17] == 1'b1) ? {7'hff, d} : {7'h00, d}; 47 48 generate 49 case(DEVICE) 50 // begin generate virtex6 51 "VIRTEX6", "7SERIES" : 52 begin 53 DSP48E1 #( 54 .ACASCREG(AREG_IN), 55 .AREG(AREG_IN), 56 .BCASCREG(BREG_IN), 57 .BREG(BREG_IN), 58 .MREG(MREG_IN), 59 .PREG(PREG_IN), 60 .USE_DPORT("TRUE") 61 ) 62 DSP48E_BL ( 63 .ACOUT(), 64 .BCOUT(), 65 .CARRYCASCOUT(), 66 .CARRYOUT(), 67 .MULTSIGNOUT(), 68 .OVERFLOW(), 69 .P(acc), 70 .PATTERNBDETECT(), 71 .PATTERNDETECT(), 72 .PCOUT(), 73 .UNDERFLOW(), 74 .A({5'b0, a_in[24:0]}), 75 .ACIN(30'b0), 76 .ALUMODE(4'b0000), 77 .B(b[17:0]), 78 .BCIN(18'b0), 79 .C(c), 80 .CARRYCASCIN(1'b0), 81 .CARRYIN(carryin), 82 .CARRYINSEL(3'b0), 83 .CEA1(1'b0), 84 .CEA2(ce), 85 .CEAD(ce), 86 .CEALUMODE(ce), 87 .CEB1(1'b0), 88 .CEB2(ce), 89 .CEC(ce), 90 .CECARRYIN(ce), 91 .CECTRL(ce), 92 .CED(ce), 93 .CEINMODE(ce), 94 .CEM(ce), 95 .CEP(ce), 96 .CLK(clk), 97 .D(d_in[24:0]), 98 .INMODE(5'b00100), 99 .MULTSIGNIN(1'b0), 100 .OPMODE({2'b01,load,4'b0101}), 101 .PCIN(48'b0), 102 .RSTA(rst), 103 .RSTALLCARRYIN(rst), 104 .RSTALUMODE(rst), 105 .RSTB(rst), 106 .RSTC(rst), 107 .RSTCTRL(rst), 108 .RSTD(rst), 109 .RSTINMODE(rst), 110 .RSTM(rst), 111 .RSTP(rst) 112 ); 113 end // end generate virtex6 114 // begin generate spartan6 115 "SPARTAN6" : 116 begin 117 // DSP48A1 has 18b+18b=18b pre-adder, must discard LSB of A and D and compensate by shifting ACC. 118 wire discard;; 119 assign acc[0] = 1'b0; 120 121 DSP48A1 #( 122 .A0REG(A0REG_IN), 123 .A1REG(A1REG_IN), 124 .B0REG(B0REG_IN), 125 .B1REG(B1REG_IN), 126 .MREG(MREG_IN), 127 .PREG(PREG_IN) 128 ) 129 DSP48AST ( 130 .BCOUT(), 131 .CARRYOUT(), 132 .CARRYOUTF(), 133 .M(), 134 .P({discard,acc[47:1]}), 135 .PCOUT(), 136 .A(b[17:0]), 137 .B({a_in[17],a_in[17:1]}), 138 .C(c), 139 .CARRYIN(carryin), 140 .CEA(ce), 141 .CEB(ce), 142 .CEC(ce), 143 .CECARRYIN(ce), 144 .CED(ce), 145 .CEM(ce), 146 .CEOPMODE(ce), 147 .CEP(ce), 148 .CLK(clk), 149 .D({d_in[17],d_in[17:1]}), 150 .OPMODE({5'b00011,load, 2'b01}), 151 .PCIN(48'b0), 152 .RSTA(rst), 153 .RSTB(rst), 154 .RSTC(rst), 155 .RSTCARRYIN(rst), 156 .RSTD(rst), 157 .RSTM(rst), 158 .RSTOPMODE(rst), 159 .RSTP(rst) 160 ); 161 end // end generate spartan6 162 endcase 163 endgenerate 164endmodule 165