I have been working on implementing this on the OSSC. This is the function I am using now:
function [7:0] apply_reverse_lpf; input enable; input [7:0] data; input [7:0] data_prev; input [8:0] lpfv; int a, b, c; begin a = data_prev << 7; b = (data_prev - data) * lpfv; c = (a < b ? 0 : (a - b)); if (enable) apply_reverse_lpf = (c > (255 << 7)) ? 8'hFF : (c >> 7); else apply_reverse_lpf = data; end endfunction
The function compares current to previous pixel and of course for the 256×240 optimized mode the source pixels are repeated so it should only store the previous pixel at the last repeated pixel.
I check when linebuf_hoffset changes and it seems to change at the third repeat. So I use lpf_last_hoffset to store the previous pixel at the following cycle.
I added this after calling the reverse_lpf function:
if ((V_MULTMODE == V_MULTMODE_3X) & (H_MULTMODE == H_MULTMODE_OPTIMIZED)) begin if (lpf_last_hoffset == 1'b1) begin R_prev <= R_act; G_prev <= G_act; B_prev <= B_act; end if (linebuf_hoffset_prev != linebuf_hoffset) lpf_last_hoffset <= 1'b1; else lpf_last_hoffset <= 1'b0; linebuf_hoffset_prev <= linebuf_hoffset; end else begin R_prev <= R_act; G_prev <= G_act; B_prev <= B_act; end
Any improvement suggestions are welcome. There is probably a better way to check the input pixel offset.
Here is a picture of it in action in lineX3 optimized: