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
|
/*
* f15_maxhold.v
*
* Computes the max hold (with epsilon decay)
*
* Copyright (C) 2015 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_maxhold #(
parameter integer Y_WIDTH = 12,
parameter integer X_WIDTH = 16,
parameter integer FRAC_WIDTH = 8
)(
input wire [Y_WIDTH-1:0] yin_0,
input wire [X_WIDTH-1:0] x_0,
input wire [15:0] rng_0,
input wire [15:0] epsilon_0,
input wire clear_0,
output wire [Y_WIDTH-1:0] yout_4,
input wire clk,
input wire rst
);
localparam integer I_WIDTH = X_WIDTH + FRAC_WIDTH;
// Signals
reg [X_WIDTH-1:0] x_1;
reg [I_WIDTH :0] y_1;
reg [Y_WIDTH :0] d_1;
reg clear_1;
reg [Y_WIDTH-1:0] y_2;
// Stage 1
always @(posedge clk)
begin
x_1 <= x_0;
y_1 <= { 1'b0, yin_0, rng_0[I_WIDTH-Y_WIDTH-1:0] } - epsilon_0;
d_1 <= { 1'b0, yin_0 } - { 1'b0, x_0[X_WIDTH-1:X_WIDTH-Y_WIDTH] };
clear_1 <= clear_0;
end
// Stage 2
always @(posedge clk)
begin
if (clear_1)
y_2 <= 0;
else if (d_1[Y_WIDTH])
// x is larger, use this
y_2 <= x_1[X_WIDTH-1:X_WIDTH-Y_WIDTH];
else
// y is larger, take old y with small decay
if (y_1[I_WIDTH])
y_2 <= 0;
else
y_2 <= y_1[I_WIDTH-1:I_WIDTH-Y_WIDTH];
end
// Apply two more delay to match the avg block
delay_bus #(2, Y_WIDTH) dl_y (y_2, yout_4, clk);
endmodule // f15_maxhold
|