1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/*
* f15_rise_decay.v
*
* Applies the rise or decay to a given value.
*
* Copyright (C) 2014 Ettus Corporation LLC
* Copyright 2018 Ettus Research, a National Instruments Company
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* vim: ts=4 sw=4
*/
`ifdef SIM
`default_nettype none
`endif
module f15_rise_decay #(
parameter integer WIDTH = 9
)(
input wire [WIDTH-1:0] in_0, // input
output reg [WIDTH-1:0] out_5, // output
input wire [15:0] k_0, // time constant
input wire ena_0, // If ena=0, then output original value
input wire mode_0, // 0=rise, 1=decay
input wire [15:0] rng,
input wire clk,
input wire rst
);
// Signals
reg mode_1;
reg [4:0] inmode_1;
wire [WIDTH-1:0] in_2;
wire ena_2;
wire [6:0] opmode_2;
reg [3:0] alumode_2;
wire [47:0] pout_4;
wire pmatch_4;
// Main DSP
// --------
// Mode control
// For rise we have INMODE=00000 (A=A2, B=B2), ALUMODE=0000 (C+M)
// For decay we have INMODE=01100 (A=D-A2, B=B2), ALUMODE=0011 (C-M)
always @(posedge clk)
begin
mode_1 <= mode_0;
if (mode_0)
inmode_1 <= 5'b00000;
else
inmode_1 <= 5'b01100;
if (mode_1)
alumode_2 <= 4'b0011;
else
alumode_2 <= 4'b0000;
end
// When not enabled, we use OPMODE to do pass-through
delay_bit #(2) dl_ena (ena_0, ena_2, clk);
assign opmode_2 = ena_2 ? 7'b0110101 : 7'b0110000;
// Delay for input to C
delay_bus #(2, WIDTH) dl_in (in_0, in_2, clk);
// Instance
DSP48E1 #(
.A_INPUT("DIRECT"),
.B_INPUT("DIRECT"),
.USE_DPORT("TRUE"),
.USE_MULT("MULTIPLY"),
.AUTORESET_PATDET("NO_RESET"),
.MASK({1'b1, {(31-WIDTH){1'b0}}, {(WIDTH+16){1'b1}}}),
.PATTERN(48'h000000000000),
.SEL_MASK("MASK"),
.SEL_PATTERN("PATTERN"),
.USE_PATTERN_DETECT("PATDET"),
.ACASCREG(1),
.ADREG(1),
.ALUMODEREG(1),
.AREG(1),
.BCASCREG(2),
.BREG(2),
.CARRYINREG(1),
.CARRYINSELREG(1),
.CREG(1),
.DREG(1),
.INMODEREG(1),
.MREG(1),
.OPMODEREG(1),
.PREG(1),
.USE_SIMD("ONE48")
)
dsp_exp_I (
.PATTERNDETECT(pmatch_4),
.P(pout_4),
.ACIN(30'h0),
.BCIN(18'h0),
.CARRYCASCIN(1'h0),
.MULTSIGNIN(1'h0),
.PCIN(48'h000000000000),
.ALUMODE(alumode_2),
.CARRYINSEL(3'h0),
.CEINMODE(1'b1),
.CLK(clk),
.INMODE(inmode_1),
.OPMODE(opmode_2),
.RSTINMODE(rst),
.A({{(30-WIDTH){1'b0}}, in_0}),
.B({ 2'h0, k_0}),
.C({{(32-WIDTH){1'b0}}, in_2, rng}),
.CARRYIN(1'b0),
.D({{(24-WIDTH){1'b0}}, 1'b1, {WIDTH{1'b0}}}),
.CEA1(1'b0),
.CEA2(1'b1),
.CEAD(1'b1),
.CEALUMODE(1'b1),
.CEB1(1'b1),
.CEB2(1'b1),
.CEC(1'b1),
.CECARRYIN(1'b1),
.CECTRL(1'b1),
.CED(1'b1),
.CEM(1'b1),
.CEP(1'b1),
.RSTA(rst),
.RSTALLCARRYIN(rst),
.RSTALUMODE(rst),
.RSTB(rst),
.RSTC(rst),
.RSTCTRL(rst),
.RSTD(rst),
.RSTM(rst),
.RSTP(rst)
);
// Saturation
// ----------
always @(posedge clk)
begin
if (rst == 1)
out_5 <= 0;
else
if (pout_4[47] == 1)
out_5 <= {WIDTH{1'b0}};
else if (pmatch_4 == 0)
out_5 <= {WIDTH{1'b1}};
else
out_5 <= pout_4[WIDTH+15:16];
end
endmodule // f15_rise_decay
|