0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2025-11-09 21:27:59 +00:00

92 lines
2.4 KiB
Verilog

// SPDX-FileCopyrightText: 2025 Igor Brkic <igor@hyperglitch.com>
// SPDX-License-Identifier: GPL-3.0-or-later
module auto_range #(
parameter WIDTH = 16
)(
input wire i_clk,
input wire i_rst,
input wire i_trigger,
input signed [WIDTH-1:0] isense,
output reg [2:0] range_sel
);
reg signed [WIDTH-1:0] prev_isense;
reg signed [WIDTH-1:0] delta;
reg signed [WIDTH-1+7:0] pred;
reg trigger_old = 1'b0;
localparam [4:0] DELAY_CNT_MAX = 8;
reg [4:0] delay_cnt;
localparam [2:0] RANGE_SWITCH_HIGHEST = 3'd0;
localparam [2:0] RANGE_SWITCH_LOWEST = 3'd4;
localparam signed [WIDTH-1:0] THRESHOLD_HIGH = -1048;
localparam signed [WIDTH-1:0] THRESHOLD_LOW = -22400;
// Optional simple 3-sample median filter
reg [WIDTH-1:0] s0, s1, s2;
wire [WIDTH-1:0] med;
assign med = (s0 < s1) ?
((s1 < s2)? s1 : (s0 < s2)? s2 : s0) :
((s0 < s2)? s0 : (s1 < s2)? s2 : s1);
// FIXME: median disabled to save few LUTs but it
// much better with it enabled
// median enable
//wire [WIDTH-1:0] cur = med;
wire [WIDTH-1:0] cur = isense;
// TODO: add switching for negative values
always @(posedge i_clk or posedge i_rst) begin
if (i_rst) begin
prev_isense <= 0;
delta <= 0;
delay_cnt <= 0;
range_sel <= 3'd0;
trigger_old <= 1'b0;
end else begin
if (i_trigger == 1'b1 && trigger_old == 1'b0) begin
delay_cnt <= delay_cnt + 1;
// median filter
s2 <= s1;
s1 <= s0;
s0 <= isense;
delta <= $signed(cur) - $signed(prev_isense);
pred <= $signed(cur) + delta; // TODO: add some scaling to delta
if (delay_cnt != 0) begin
delay_cnt <= delay_cnt - 1;
end else begin
if((pred<0 && pred > -512) || (pred>0 && pred < 512)) begin
// switch to lower range
if (range_sel < RANGE_SWITCH_LOWEST) begin
range_sel <= range_sel + 1;
delay_cnt <= DELAY_CNT_MAX;
end
end else if((pred<0 && pred < -22400) || (pred>0 && pred > 22400)) begin
// switch to higher range
if (range_sel > RANGE_SWITCH_HIGHEST) begin
range_sel <= range_sel - 1;
delay_cnt <= DELAY_CNT_MAX;
end
end else begin
// keep the same range
end
end
prev_isense <= cur;
end
trigger_old <= i_trigger;
end
end
endmodule