mirror of
https://gitlab.com/hyperglitch/jellyfish.git
synced 2025-11-09 21:27:59 +00:00
92 lines
2.4 KiB
Verilog
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
|
|
|
|
|