diff options
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/fosphor/f15_maxhold.v')
-rw-r--r-- | fpga/usrp3/lib/rfnoc/fosphor/f15_maxhold.v | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/fosphor/f15_maxhold.v b/fpga/usrp3/lib/rfnoc/fosphor/f15_maxhold.v new file mode 100644 index 000000000..ecd92adfb --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/fosphor/f15_maxhold.v @@ -0,0 +1,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 |