Update sys.

This commit is contained in:
Sorgelig
2022-03-26 21:34:40 +08:00
parent 1033c9bdc1
commit 94f8cd36ec
5 changed files with 238 additions and 214 deletions

View File

@@ -15,6 +15,7 @@ set_global_assignment -name VHDL_FILE rtl/bus_savestates.vhd
set_global_assignment -name VHDL_FILE rtl/reg_savestates.vhd
set_global_assignment -name VHDL_FILE rtl/gb_statemanager.vhd
set_global_assignment -name VHDL_FILE rtl/gb_savestates.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/savestate_ui.sv
set_global_assignment -name VERILOG_FILE rtl/gb.v
set_global_assignment -name VERILOG_FILE rtl/hdma.v
set_global_assignment -name VERILOG_FILE rtl/link.v
@@ -35,5 +36,4 @@ set_global_assignment -name VERILOG_FILE rtl/mappers/tama.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/mappers/rocket.sv
set_global_assignment -name VERILOG_FILE rtl/mappers/sachen.v
set_global_assignment -name SDC_FILE Gameboy.sdc
set_global_assignment -name SYSTEMVERILOG_FILE rtl/savestate_ui.sv
set_global_assignment -name SYSTEMVERILOG_FILE Gameboy.sv

View File

@@ -175,6 +175,7 @@ module screen_rotate
input rotate_ccw,
input no_rotate,
input flip,
output video_rotated,
output FB_EN,
output [4:0] FB_FORMAT,
@@ -221,6 +222,8 @@ function [1:0] buf_next;
end
endfunction
assign video_rotated = ~no_rotate;
always @(posedge CLK_VIDEO) begin
do_flip <= no_rotate && flip;
if( do_flip ) begin

View File

@@ -124,7 +124,7 @@ ENTITY ascal IS
PALETTE2 : boolean := true;
ADAPTIVE : boolean := true;
DOWNSCALE_NN : boolean := false;
FRAC : natural RANGE 4 TO 6 :=4;
FRAC : natural RANGE 4 TO 8 :=4;
OHRES : natural RANGE 1 TO 4096 :=2048;
IHRES : natural RANGE 1 TO 2048 :=2048;
N_DW : natural RANGE 64 TO 128 := 128;
@@ -231,7 +231,7 @@ ENTITY ascal IS
-- [0]...[2**FRAC-1]
-- [-1][0][1][2]
poly_clk : IN std_logic;
poly_dw : IN unsigned(8 DOWNTO 0);
poly_dw : IN unsigned(9 DOWNTO 0);
poly_a : IN unsigned(FRAC+3 DOWNTO 0);
poly_wr : IN std_logic;
@@ -305,10 +305,11 @@ ARCHITECTURE rtl OF ascal IS
TYPE arr_uv48 IS ARRAY (natural RANGE <>) OF unsigned(47 DOWNTO 0);
TYPE arr_uv24 IS ARRAY (natural RANGE <>) OF unsigned(23 DOWNTO 0);
TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0);
TYPE arr_uv40 IS ARRAY (natural RANGE <>) OF unsigned(39 DOWNTO 0);
TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255;
TYPE arr_uint12 IS ARRAY (natural RANGE <>) OF uint12;
TYPE arr_frac IS ARRAY (natural RANGE <>) OF unsigned(11 DOWNTO 0);
TYPE arr_div IS ARRAY (natural RANGE <>) OF unsigned(20 DOWNTO 0);
----------------------------------------------------------
-- Input image
@@ -434,7 +435,7 @@ ARCHITECTURE rtl OF ascal IS
SIGNAL o_pshift : natural RANGE 0 TO 15;
SIGNAL o_readack,o_readack_sync,o_readack_sync2 : std_logic;
SIGNAL o_readdataack,o_readdataack_sync,o_readdataack_sync2 : std_logic;
SIGNAL o_copyv : unsigned(0 TO 11);
SIGNAL o_copyv : unsigned(0 TO 12);
SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address
SIGNAL o_adrs_pre : natural RANGE 0 TO 2**24-1;
SIGNAL o_stride : unsigned(13 DOWNTO 0);
@@ -481,7 +482,7 @@ ARCHITECTURE rtl OF ascal IS
TYPE arr_uint4 IS ARRAY (natural RANGE <>) OF natural RANGE 0 TO 15;
SIGNAL o_off : arr_uint4(0 TO 2);
SIGNAL o_bibu : std_logic :='0';
SIGNAL o_dcptv : arr_uint12(1 TO 11);
SIGNAL o_dcptv : arr_uint12(1 TO 12);
SIGNAL o_dcpt : uint12;
SIGNAL o_hpixs,o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix;
SIGNAL o_hpixq : arr_pixq(2 TO 6);
@@ -494,8 +495,9 @@ ARCHITECTURE rtl OF ascal IS
SIGNAL o_vpe : std_logic;
SIGNAL o_div,o_div2 : unsigned(18 DOWNTO 0); --uint12;
SIGNAL o_dir,o_dir2 : unsigned(11 DOWNTO 0);
SIGNAL o_div : arr_div(0 TO 2); --uint12;
SIGNAL o_dir : arr_frac(0 TO 2);
ATTRIBUTE ramstyle OF o_div, o_dir : SIGNAL IS "logic"; -- avoid blockram shift register
SIGNAL o_vdivi : unsigned(12 DOWNTO 0);
SIGNAL o_vdivr : unsigned(24 DOWNTO 0);
SIGNAL o_divstart : std_logic;
@@ -947,39 +949,9 @@ ARCHITECTURE rtl OF ascal IS
-----------------------------------------------------------------------------
-- Polyphase
CONSTANT POLY16 : arr_int9 := (
-24,-21,-15,-9,-5,-1,4,8,6,8,5,4,3,1,0,0,
176,174,169,160,150,131,115,85,58,27,4,-6,-20,-24,-26,-25,
-24,-25,-26,-24,-20,-6,4,27,58,85,115,131,150,160,169,174,
0,0,0,1,3,4,5,8,6,8,4,-1,-5,-9,-15,-21);
CONSTANT POLY32 : arr_int9 := (
-24,-22,-20,-18,-16,-13,-11,-8,-6,-3,-1,0,2,3,5,5,6,6,6,5,5,4,4,3,2,1,1,0,0,0,0,0,
176,175,174,172,169,164,160,153,147,138,129,119,109,96,84,71,58,40,22,12,3,-4,-12,-16,-20,-22,-25,-25,-26,-25,-25,-25,
-24,-25,-26,-26,-26,-24,-23,-19,-16,-10,-4,4,11,22,32,45,58,77,96,108,119,129,140,147,154,159,165,168,172,173,175,175,
0,0,0,0,1,1,2,2,3,3,4,5,6,7,7,7,6,5,4,3,1,-1,-4,-6,-8,-10,-13,-15,-18,-20,-22,-22);
FUNCTION init_poly RETURN arr_uv36 IS
VARIABLE m : arr_uv36(0 TO 2**FRAC-1) :=(OTHERS =>x"000000000");
BEGIN
IF FRAC=4 THEN
FOR i IN 0 TO 15 LOOP
m(i):=unsigned(to_signed(POLY16(i),9) & to_signed(POLY16(i+16),9) &
to_signed(POLY16(i+32),9) & to_signed(POLY16(i+48),9));
END LOOP;
ELSIF FRAC=5 THEN
FOR i IN 0 TO 31 LOOP
m(i):=unsigned(to_signed(POLY32(i),9) & to_signed(POLY32(i+32),9) &
to_signed(POLY32(i+64),9) & to_signed(POLY32(i+96),9));
END LOOP;
END IF;
RETURN m;
END FUNCTION;
-- 2.7
TYPE poly_phase_t IS RECORD
t0, t1, t2, t3 : signed(8 DOWNTO 0);
t0, t1, t2, t3 : signed(9 DOWNTO 0);
END RECORD;
-- 4.14
@@ -991,10 +963,11 @@ ARCHITECTURE rtl OF ascal IS
TYPE type_poly_t IS RECORD
r0,r1,b0,b1,g0,g1 : signed(26 DOWNTO 0);
END RECORD;
SIGNAL o_h_poly_mem : arr_uv36(0 TO 2**FRAC-1):=init_poly;
SIGNAL o_v_poly_mem : arr_uv36(0 TO 2**FRAC-1):=init_poly;
SIGNAL o_a_poly_mem : arr_uv36(0 TO 2**FRAC-1):=init_poly;
SIGNAL o_h_poly_mem : arr_uv40(0 TO 2**FRAC-1);
SIGNAL o_v_poly_mem : arr_uv40(0 TO 2**FRAC-1);
SIGNAL o_a_poly_mem : arr_uv40(0 TO 2**FRAC-1);
ATTRIBUTE ramstyle OF o_h_poly_mem : SIGNAL IS "no_rw_check";
ATTRIBUTE ramstyle OF o_v_poly_mem : SIGNAL IS "no_rw_check";
ATTRIBUTE ramstyle OF o_a_poly_mem : SIGNAL IS "no_rw_check";
@@ -1008,21 +981,20 @@ ARCHITECTURE rtl OF ascal IS
SIGNAL o_v_poly_lum, o_h_poly_lum, o_poly_lum : unsigned(7 DOWNTO 0);
SIGNAL o_poly_lerp_ta, o_poly_lerp_tb, o_poly_lerp_tb3 : signed(9 DOWNTO 0);
SIGNAL o_h_poly_t,o_h_poly_t2,o_v_poly_t : type_poly_t;
SIGNAL o_h_poly_lum0,o_h_poly_lum1,o_h_poly_lum2 : unsigned(7 DOWNTO 0);
SIGNAL o_v_poly_adaptive, o_h_poly_adaptive, o_v_poly_use_adaptive, o_h_poly_use_adaptive : std_logic;
SIGNAL poly_wr_mode : std_logic_vector(2 DOWNTO 0);
SIGNAL poly_tdw : unsigned(35 DOWNTO 0);
SIGNAL poly_tdw : unsigned(39 DOWNTO 0);
SIGNAL poly_a2 : unsigned(FRAC-1 DOWNTO 0);
FUNCTION poly_unpack(a : unsigned(35 DOWNTO 0)) RETURN poly_phase_t IS
FUNCTION poly_unpack(a : unsigned(39 DOWNTO 0)) RETURN poly_phase_t IS
VARIABLE v : poly_phase_t;
BEGIN
v.t0 := signed(a(35 DOWNTO 27));
v.t1 := signed(a(26 DOWNTO 18));
v.t2 := signed(a(17 DOWNTO 9));
v.t3 := signed(a( 8 DOWNTO 0));
v.t0 := signed(a(39 DOWNTO 30));
v.t1 := signed(a(29 DOWNTO 20));
v.t2 := signed(a(19 DOWNTO 10));
v.t3 := signed(a( 9 DOWNTO 0));
RETURN v;
END FUNCTION;
@@ -1063,19 +1035,19 @@ ARCHITECTURE rtl OF ascal IS
ta : SIGNED(9 DOWNTO 0);
tb : SIGNED(9 DOWNTO 0)) RETURN poly_phase_interp_t IS
VARIABLE v : poly_phase_interp_t;
VARIABLE t0,t1,t2,t3 : signed(18 DOWNTO 0);
VARIABLE t0,t1,t2,t3 : signed(19 DOWNTO 0);
BEGIN
-- 2.7 * 2.8 = 4.15
-- 2.8 * 2.8 = 4.16
t0 := (a.t0 * ta) + (b.t0 * tb);
t1 := (a.t1 * ta) + (b.t1 * tb);
t2 := (a.t2 * ta) + (b.t2 * tb);
t3 := (a.t3 * ta) + (b.t3 * tb);
-- 4.15 -> 3.15
v.t0 := t0(17 DOWNTO 0);
v.t1 := t1(17 DOWNTO 0);
v.t2 := t2(17 DOWNTO 0);
v.t3 := t3(17 DOWNTO 0);
-- 4.16 -> 3.15
v.t0 := t0(18 DOWNTO 1);
v.t1 := t1(18 DOWNTO 1);
v.t2 := t2(18 DOWNTO 1);
v.t3 := t3(18 DOWNTO 1);
RETURN v;
END FUNCTION;
@@ -1083,10 +1055,10 @@ ARCHITECTURE rtl OF ascal IS
FUNCTION poly_cvt(a : poly_phase_t) RETURN poly_phase_interp_t IS
VARIABLE v : poly_phase_interp_t;
BEGIN
v.t0 := resize(signed( a.t0 & "00000000" ), v.t0'length);
v.t1 := resize(signed( a.t1 & "00000000" ), v.t1'length);
v.t2 := resize(signed( a.t2 & "00000000" ), v.t2'length);
v.t3 := resize(signed( a.t3 & "00000000" ), v.t3'length);
v.t0 := resize(signed( a.t0 & "0000000" ), v.t0'length);
v.t1 := resize(signed( a.t1 & "0000000" ), v.t1'length);
v.t2 := resize(signed( a.t2 & "0000000" ), v.t2'length);
v.t3 := resize(signed( a.t3 & "0000000" ), v.t3'length);
RETURN v;
END FUNCTION;
@@ -1095,9 +1067,9 @@ ARCHITECTURE rtl OF ascal IS
VARIABLE v : poly_phase_t;
BEGIN
IF frac(frac'left)='0' THEN
v := (t1=>to_signed(128, 9), OTHERS=>to_signed(0, 9));
v := (t1=>to_signed(256, 10), OTHERS=>to_signed(0, 10));
ELSE
v := (t2=>to_signed(128, 9), OTHERS=>to_signed(0, 9));
v := (t2=>to_signed(256, 10), OTHERS=>to_signed(0, 10));
END IF;
RETURN v;
END FUNCTION;
@@ -1110,11 +1082,22 @@ ARCHITECTURE rtl OF ascal IS
--v := ("00" & p.r(7 DOWNTO 2)) + ("000" & p.r(7 DOWNTO 3)) + ("0" & p.g(7 DOWNTO 1)) + ("000" & p.b(7 DOWNTO 3));
-- 0.25 R + 0.5 G + 0.25 B
v := ( ("00" & p.r(7 DOWNTO 2)) + ("0" & p.g(7 DOWNTO 1)) + ("00" & p.b(7 DOWNTO 2)) );
-- v := ( ("00" & p.r(7 DOWNTO 2)) + ("0" & p.g(7 DOWNTO 1)) + ("00" & p.b(7 DOWNTO 2)) );
-- Just OR them all together
-- v := (p.r OR p.g OR p.b);
--v := (p.r OR p.g OR p.b);
-- Maximum
IF p.r > p.g THEN
v := p.r;
ELSE
v := p.g;
END IF;
IF p.b > v THEN
v := p.b;
END IF;
-- 100%
-- v := "1111111";
@@ -1831,7 +1814,6 @@ BEGIN
VARIABLE prim_v,last_v,bib_v : std_logic;
VARIABLE shift_v : unsigned(0 TO N_DW+15);
VARIABLE hpix_v : type_pix;
VARIABLE hlum_v : unsigned(7 DOWNTO 0);
VARIABLE hcarry_v,vcarry_v : boolean;
VARIABLE dif_v : natural RANGE 0 TO 8*OHRES-1;
VARIABLE off_v : natural RANGE 0 TO 15;
@@ -2233,24 +2215,15 @@ BEGIN
o_hpix2<=o_hpix1;
o_hpix3<=o_hpix2;
hlum_v:=poly_lum(hpix_v);
o_h_poly_lum0<=hlum_v;
o_h_poly_lum1<=o_h_poly_lum0;
o_h_poly_lum2<=o_h_poly_lum1;
IF o_first='1' THEN
-- Left edge. Duplicate first pixel
o_hpix1<=hpix_v;
o_hpix2<=hpix_v;
o_h_poly_lum1<=hlum_v;
o_h_poly_lum2<=hlum_v;
o_first<='0';
END IF;
IF o_lastt4='1' THEN
-- Right edge. Keep last pixel.
o_hpix0<=o_hpix0;
o_h_poly_lum0<=o_h_poly_lum0;
END IF;
END IF;
@@ -2304,28 +2277,27 @@ BEGIN
-- Fetch polyphase coefficients
PolyFetch:PROCESS (o_clk) IS
VARIABLE hfrac1_v, hfrac2_v, vfrac_v : unsigned(FRAC-1 DOWNTO 0);
VARIABLE lum_v : unsigned(7 DOWNTO 0);
VARIABLE hfrac2_v, hfrac3_v, vfrac_v : unsigned(FRAC-1 DOWNTO 0);
VARIABLE o_poly_phase_v : poly_phase_interp_t;
BEGIN
IF rising_edge(o_clk) THEN
hfrac1_v:=o_hfrac(1)(11 DOWNTO 12-FRAC);
hfrac2_v:=o_hfrac(2)(11 DOWNTO 12-FRAC);
hfrac3_v:=o_hfrac(3)(11 DOWNTO 12-FRAC);
vfrac_v:=o_vfrac(11 DOWNTO 12-FRAC);
o_v_poly_use_adaptive <= to_std_logic((o_vmode(2 DOWNTO 0)/="000") AND (o_v_poly_adaptive = '1'));
o_h_poly_use_adaptive <= to_std_logic((o_hmode(2 DOWNTO 0)/="000") AND (o_h_poly_adaptive = '1'));
-- C2 / HC1 / VC3
-- C2 / HC2 / VC3
o_v_poly_addr<=to_integer(vfrac_v);
o_h_poly_addr<=to_integer(hfrac1_v);
o_h_poly_addr<=to_integer(hfrac2_v);
IF o_v_poly_use_adaptive = '1' THEN
o_a_poly_addr<=to_integer(vfrac_v);
ELSIF o_h_poly_use_adaptive = '1' THEN
o_a_poly_addr<=to_integer(hfrac1_v);
o_a_poly_addr<=to_integer(hfrac2_v);
END IF;
-- C3 / HC2 / VC4
-- C3 / HC3 / VC4
IF o_vmode(2 DOWNTO 0)/="000" THEN
o_v_poly_phase_a<=poly_unpack(o_v_poly_mem(o_v_poly_addr));
ELSE
@@ -2335,22 +2307,18 @@ BEGIN
IF o_hmode(2 DOWNTO 0)/="000" THEN
o_h_poly_phase_a<=poly_unpack(o_h_poly_mem(o_h_poly_addr));
ELSE
o_h_poly_phase_a<=poly_nn(hfrac2_v);
o_h_poly_phase_a<=poly_nn(hfrac3_v);
END IF;
IF o_v_poly_use_adaptive='1' THEN
o_poly_lum<=o_v_poly_lum;
ELSIF o_h_poly_use_adaptive='1' THEN
IF hfrac2_v(hfrac2_v'left)='0' THEN
o_poly_lum<=o_h_poly_lum2;
ELSE
o_poly_lum<=o_h_poly_lum1;
END IF;
o_poly_lum<=o_h_poly_lum;
END IF;
o_poly_phase_b<=poly_unpack(o_a_poly_mem(o_a_poly_addr));
-- C4 / HC3 / VC5
-- C4 / HC4 / VC5
o_poly_lerp_ta<=signed(to_unsigned(256,10) - resize(o_poly_lum,10));
o_poly_lerp_tb<=signed(resize(o_poly_lum,10));
@@ -2364,12 +2332,12 @@ BEGIN
o_v_poly_phase_a2<=o_v_poly_phase_a;
o_poly_phase_b2<=o_poly_phase_b;
-- C5 / HC4 / VC6
-- C5 / HC5 / VC6
o_poly_phase<=poly_lerp(o_poly_phase_a, o_poly_phase_b2, o_poly_lerp_ta, o_poly_lerp_tb);
o_h_poly_phase_a3<=o_h_poly_phase_a2;
o_v_poly_phase_a3<=o_v_poly_phase_a2;
-- C6 / HC5 / VC7
-- C6 / HC6 / VC7
o_v_poly_phase<=poly_cvt(o_v_poly_phase_a3);
o_h_poly_phase<=poly_cvt(o_h_poly_phase_a3);
@@ -2429,8 +2397,8 @@ BEGIN
BEGIN
IF rising_edge(poly_clk) THEN
IF poly_wr='1' THEN
poly_tdw(8+9*(3-to_integer(poly_a(1 DOWNTO 0))) DOWNTO
9*(3-to_integer(poly_a(1 DOWNTO 0))))<=poly_dw;
poly_tdw(9+10*(3-to_integer(poly_a(1 DOWNTO 0))) DOWNTO
10*(3-to_integer(poly_a(1 DOWNTO 0))))<=poly_dw;
END IF;
poly_wr_mode(0)<=poly_wr AND NOT poly_a(FRAC+2);
@@ -2459,131 +2427,160 @@ BEGIN
-----------------------------------------------------------------------------
-- Horizontal Scaler
HSCAL:PROCESS(o_clk) IS
VARIABLE div_v : unsigned(18 DOWNTO 0);
VARIABLE div_v : unsigned(20 DOWNTO 0);
VARIABLE dir_v : unsigned(11 DOWNTO 0);
BEGIN
IF rising_edge(o_clk) THEN
-- Pipeline signals
-----------------------------------
-- Pipelined 6 bits non-restoring divider. Cycle 1
-- Pipelined 8 bits non-restoring divider. Cycle 1
dir_v:=x"000";
div_v:=to_unsigned(o_hacc * 64,19);
div_v:=to_unsigned(o_hacc * 256,21);
div_v:=div_v-to_unsigned(o_hsize*64,19);
dir_v(11):=NOT div_v(18);
IF div_v(18)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*32,19);
div_v:=div_v-to_unsigned(o_hsize*256,21);
dir_v(11):=NOT div_v(20);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*128,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*32,19);
div_v:=div_v+to_unsigned(o_hsize*128,21);
END IF;
dir_v(10):=NOT div_v(18);
o_div<=div_v;
o_dir<=dir_v;
dir_v(10):=NOT div_v(20);
o_div(0)<=div_v;
o_dir(0)<=dir_v;
-- Cycle 2
div_v:=o_div;
dir_v:=o_dir;
IF div_v(18)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*16,19);
div_v:=o_div(0);
dir_v:=o_dir(0);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*64,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*16,19);
div_v:=div_v+to_unsigned(o_hsize*64,21);
END IF;
dir_v( 9):=NOT div_v(18);
dir_v( 9):=NOT div_v(20);
IF div_v(18)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*8,19);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*32,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*8,19);
div_v:=div_v+to_unsigned(o_hsize*32,21);
END IF;
dir_v(8):=NOT div_v(18);
o_div2<=div_v;
o_dir2<=dir_v;
dir_v( 8):=NOT div_v(20);
o_div(1)<=div_v;
o_dir(1)<=dir_v;
-- Cycle 3
div_v:=o_div2;
dir_v:=o_dir2;
div_v:=o_div(1);
dir_v:=o_dir(1);
IF FRAC>4 THEN
IF div_v(18)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*4,19);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*16,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*4,19);
div_v:=div_v+to_unsigned(o_hsize*16,21);
END IF;
dir_v(7):=NOT div_v(18);
IF div_v(18)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*2,19);
dir_v(7):=NOT div_v(20);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*8,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*2,19);
div_v:=div_v+to_unsigned(o_hsize*8,21);
END IF;
dir_v(6):=NOT div_v(18);
dir_v(6):=NOT div_v(20);
END IF;
o_div(2)<=div_v;
o_dir(2)<=dir_v;
div_v:=o_div(2);
dir_v:=o_dir(2);
IF FRAC>6 THEN
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*4,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*4,21);
END IF;
dir_v(5):=NOT div_v(20);
IF div_v(20)='0' THEN
div_v:=div_v-to_unsigned(o_hsize*2,21);
ELSE
div_v:=div_v+to_unsigned(o_hsize*2,21);
END IF;
dir_v(4):=NOT div_v(20);
END IF;
-----------------------------------
o_hfrac(0)<=dir_v;
o_hfrac(1 TO 6) <= o_hfrac(0 TO 5);
o_hfrac(1)<=dir_v;
o_hfrac(2 TO 6) <= o_hfrac(1 TO 5);
o_copyv(1 TO 11)<=o_copyv(0 TO 10);
o_copyv(1 TO 12)<=o_copyv(0 TO 11);
o_dcptv(1)<=o_dcpt;
IF o_dcptv(1)>=o_hsize THEN
o_copyv(2)<='0';
END IF;
o_dcptv(2)<=o_dcptv(1) MOD OHRES;
o_dcptv(3 TO 11)<=o_dcptv(2 TO 10);
o_dcptv(3 TO 12)<=o_dcptv(2 TO 11);
-- C2
o_hpixq(2)<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0);
o_hpixq(3 TO 6)<=o_hpixq(2 TO 5);
-- BILINEAR / SHARP BILINEAR ---------------
-- C3 : Pre-calc Sharp Bilinear
o_h_sbil_t<=sbil_frac1(o_hfrac(2));
-- C4 : Pre-calc Sharp Bilinear
o_h_sbil_t<=sbil_frac1(o_hfrac(3));
-- C4 : Select
-- C5 : Select
o_h_bil_frac<=(OTHERS =>'0');
IF o_hmode(0)='1' THEN -- Bilinear
IF MASK(MASK_BILINEAR)='1' THEN
o_h_bil_frac<=bil_frac(o_hfrac(3));
o_h_bil_frac<=bil_frac(o_hfrac(4));
END IF;
ELSE -- Sharp Bilinear
IF MASK(MASK_SHARP_BILINEAR)='1' THEN
o_h_bil_frac<=sbil_frac2(o_hfrac(3),o_h_sbil_t);
o_h_bil_frac<=sbil_frac2(o_hfrac(4),o_h_sbil_t);
END IF;
END IF;
-- C5 : Opposite frac
o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq(4));
-- C6 : Opposite frac
o_h_bil_t<=bil_calc(o_h_bil_frac,o_hpixq(5));
-- C6 : Bilinear / Sharp Bilinear
-- C7 : Bilinear / Sharp Bilinear
o_h_bil_pix.r<=bound(o_h_bil_t.r,8+FRAC);
o_h_bil_pix.g<=bound(o_h_bil_t.g,8+FRAC);
o_h_bil_pix.b<=bound(o_h_bil_t.b,8+FRAC);
-- BICUBIC -------------------------------------------
-- C4 : Bicubic coefficients A,B,C,D
-- C4 : Bicubic calc T1 = X.D + C
o_h_bic_abcd1<=bic_calc0(o_hfrac(3),o_hpixq(3));
o_h_bic_tt1<=bic_calc1(o_hfrac(3),
bic_calc0(o_hfrac(3),o_hpixq(3)));
-- C5 : Bicubic coefficients A,B,C,D
-- C5 : Bicubic calc T1 = X.D + C
o_h_bic_abcd1<=bic_calc0(o_hfrac(4),o_hpixq(4));
o_h_bic_tt1<=bic_calc1(o_hfrac(4),
bic_calc0(o_hfrac(4),o_hpixq(4)));
-- C5 : Bicubic calc T2 = X.T1 + B
-- C6 : Bicubic calc T2 = X.T1 + B
o_h_bic_abcd2<=o_h_bic_abcd1;
o_h_bic_tt2<=bic_calc2(o_hfrac(4),o_h_bic_tt1,o_h_bic_abcd1);
o_h_bic_tt2<=bic_calc2(o_hfrac(5),o_h_bic_tt1,o_h_bic_abcd1);
-- C6 : Bicubic final Y = X.T2 + A
o_h_bic_pix<=bic_calc3(o_hfrac(5),o_h_bic_tt2,o_h_bic_abcd2);
-- C7 : Bicubic final Y = X.T2 + A
o_h_bic_pix<=bic_calc3(o_hfrac(6),o_h_bic_tt2,o_h_bic_abcd2);
-- POLYPHASE -----------------------------------------
-- C2-C5 in PolyFetch
-- C2
IF o_hfrac(2)(o_hfrac(2)'left)='0' THEN
o_h_poly_lum<=poly_lum(o_hpix2);
ELSE
o_h_poly_lum<=poly_lum(o_hpix1);
END IF;
-- C3-C6 in PolyFetch
-- C6 : Apply Polyphase
o_h_poly_t<=poly_calc(o_h_poly_phase,o_hpixq(5));
-- C7 : Apply Polyphase
o_h_poly_t<=poly_calc(o_h_poly_phase,o_hpixq(6));
-- C7 : Sum and bound
-- C8 : Sum and bound
o_h_poly_pix<=poly_final(o_h_poly_t);
-- C8 : Select interpoler ----------------------------
o_wadl<=o_dcptv(11);
o_wr<=o_altx AND (o_copyv(11) & o_copyv(11) & o_copyv(11) & o_copyv(11));
-- C9 : Select interpoler ----------------------------
o_wadl<=o_dcptv(12);
o_wr<=o_altx AND (o_copyv(12) & o_copyv(12) & o_copyv(12) & o_copyv(12));
o_ldw<=(x"00",x"00",x"00");
CASE o_hmode(2 DOWNTO 0) IS

View File

@@ -55,6 +55,13 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [15:0] joystick_r_analog_4,
output reg [15:0] joystick_r_analog_5,
input [15:0] joystick_0_rumble, // 15:8 - 'large' rumble motor magnitude, 7:0 'small' rumble motor magnitude
input [15:0] joystick_1_rumble,
input [15:0] joystick_2_rumble,
input [15:0] joystick_3_rumble,
input [15:0] joystick_4_rumble,
input [15:0] joystick_5_rumble,
// paddle 0..255
output reg [7:0] paddle_0,
output reg [7:0] paddle_1,
@@ -71,9 +78,38 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [8:0] spinner_4,
output reg [8:0] spinner_5,
// ps2 keyboard emulation
output ps2_kbd_clk_out,
output ps2_kbd_data_out,
input ps2_kbd_clk_in,
input ps2_kbd_data_in,
input [2:0] ps2_kbd_led_status,
input [2:0] ps2_kbd_led_use,
output ps2_mouse_clk_out,
output ps2_mouse_data_out,
input ps2_mouse_clk_in,
input ps2_mouse_data_in,
// ps2 alternative interface.
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
output reg [10:0] ps2_key = 0,
// [24] - toggles with every event
output reg [24:0] ps2_mouse = 0,
output reg [15:0] ps2_mouse_ext = 0, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
output [1:0] buttons,
output forced_scandoubler,
output direct_video,
input video_rotated,
//toggle to force notify of video mode change
input new_vmode,
inout [21:0] gamma_bus,
output reg [63:0] status,
input [63:0] status_in,
@@ -83,9 +119,6 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
input info_req,
input [7:0] info,
//toggle to force notify of video mode change
input new_vmode,
// SD config
output reg [VD:0] img_mounted, // signaling that new image has been mounted
output reg img_readonly, // mounted as read only. valid only for active bit in img_mounted
@@ -132,31 +165,6 @@ module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1,
output reg [7:0] uart_mode,
output reg [31:0] uart_speed,
// ps2 keyboard emulation
output ps2_kbd_clk_out,
output ps2_kbd_data_out,
input ps2_kbd_clk_in,
input ps2_kbd_data_in,
input [2:0] ps2_kbd_led_status,
input [2:0] ps2_kbd_led_use,
output ps2_mouse_clk_out,
output ps2_mouse_data_out,
input ps2_mouse_clk_in,
input ps2_mouse_data_in,
// ps2 alternative interface.
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
output reg [10:0] ps2_key = 0,
// [24] - toggles with every event
output reg [24:0] ps2_mouse = 0,
output reg [15:0] ps2_mouse_ext = 0, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
inout [21:0] gamma_bus,
// for core-specific extensions
inout [35:0] EXT_BUS
);
@@ -216,6 +224,7 @@ video_calc video_calc
.vs_hdmi(HPS_BUS[44]),
.f1(HPS_BUS[45]),
.new_vmode(new_vmode),
.video_rotated(video_rotated),
.par_num(byte_cnt[3:0]),
.dout(vc_dout)
@@ -318,9 +327,9 @@ always@(posedge clk_sys) begin : uio_block
'h0X18: begin sd_ack <= disk[VD:0]; sdn_ack <= io_din[11:8]; end
'h29: io_dout <= {4'hA, stflg};
`ifdef MISTER_DISABLE_ADAPTIVE
'h2B: io_dout <= {HPS_BUS[48:46],4'b0010};
'h2B: io_dout <= {HPS_BUS[48:46],4'b0110};
`else
'h2B: io_dout <= {HPS_BUS[48:46],4'b0011};
'h2B: io_dout <= {HPS_BUS[48:46],4'b0111};
`endif
'h2F: io_dout <= 1;
'h32: io_dout <= gamma_bus[21];
@@ -328,6 +337,12 @@ always@(posedge clk_sys) begin : uio_block
'h39: io_dout <= 1;
'h3C: if(upload_req) begin io_dout <= {ioctl_upload_index, 8'd1}; upload_req <= 0; end
'h3E: io_dout <= 1; // shadow mask
'h003F: io_dout <= joystick_0_rumble;
'h013F: io_dout <= joystick_1_rumble;
'h023F: io_dout <= joystick_2_rumble;
'h033F: io_dout <= joystick_3_rumble;
'h043F: io_dout <= joystick_4_rumble;
'h053F: io_dout <= joystick_5_rumble;
endcase
sd_buff_addr <= 0;
@@ -847,6 +862,7 @@ module video_calc
input vs_hdmi,
input f1,
input new_vmode,
input video_rotated,
input [3:0] par_num,
output reg [15:0] dout
@@ -854,7 +870,7 @@ module video_calc
always @(posedge clk_sys) begin
case(par_num)
1: dout <= {|vid_int, vid_nres};
1: dout <= {video_rotated, |vid_int, vid_nres};
2: dout <= vid_hcnt[15:0];
3: dout <= vid_hcnt[31:16];
4: dout <= vid_vcnt[15:0];

View File

@@ -295,8 +295,8 @@ reg [31:0] cfg_custom_p2;
reg [4:0] vol_att;
initial vol_att = 5'b11111;
reg [9:0] coef_addr;
reg [8:0] coef_data;
reg [11:0] coef_addr;
reg [9:0] coef_data;
reg coef_wr = 0;
wire[12:0] ARX, ARY;
@@ -377,14 +377,14 @@ always@(posedge clk_sys) begin
cfg_set <= 0;
if(cnt<8) begin
case(cnt[2:0])
0: if(WIDTH != io_din[11:0]) WIDTH <= io_din[11:0];
1: if(HFP != io_din[11:0]) HFP <= io_din[11:0];
2: if(HS != io_din[11:0]) HS <= io_din[11:0];
3: if(HBP != io_din[11:0]) HBP <= io_din[11:0];
4: if(HEIGHT != io_din[11:0]) HEIGHT <= io_din[11:0];
5: if(VFP != io_din[11:0]) VFP <= io_din[11:0];
6: if(VS != io_din[11:0]) VS <= io_din[11:0];
7: if(VBP != io_din[11:0]) VBP <= io_din[11:0];
0: WIDTH <= io_din[11:0];
1: HFP <= io_din[11:0];
2: HS <= {io_din[15], io_din[11:0]};
3: HBP <= io_din[11:0];
4: HEIGHT <= io_din[11:0];
5: VFP <= io_din[11:0];
6: VS <= {io_din[15],io_din[11:0]};
7: VBP <= io_din[11:0];
endcase
`ifndef MISTER_DEBUG_NOHDMI
if(cnt == 1) begin
@@ -423,8 +423,8 @@ always@(posedge clk_sys) begin
if(cmd == 'h26) vol_att <= io_din[4:0];
if(cmd == 'h27) VSET <= io_din[11:0];
if(cmd == 'h2A) begin
if(cnt[0]) {coef_wr,coef_data} <= {1'b1,io_din[8:0]};
else coef_addr <= io_din[9:0];
if(cnt[0]) {coef_wr,coef_data} <= {1'b1,io_din[9:0]};
else coef_addr <= io_din[11:0];
end
if(cmd == 'h2B) scaler_flt <= io_din[2:0];
if(cmd == 'h37) {FREESCALE,HSET} <= {io_din[15],io_din[11:0]};
@@ -647,7 +647,7 @@ ascal
`ifdef MISTER_DOWNSCALE_NN
.DOWNSCALE_NN("true"),
`endif
.FRAC(6),
.FRAC(8),
.N_DW(128),
.N_AW(28)
)
@@ -683,15 +683,15 @@ ascal
.o_vbl (hdmi_vbl),
.o_brd (hdmi_brd),
.o_lltune (lltune),
.htotal (WIDTH + HFP + HBP + HS),
.htotal (WIDTH + HFP + HBP + HS[11:0]),
.hsstart (WIDTH + HFP),
.hsend (WIDTH + HFP + HS),
.hsend (WIDTH + HFP + HS[11:0]),
.hdisp (WIDTH),
.hmin (hmin),
.hmax (hmax),
.vtotal (HEIGHT + VFP + VBP + VS),
.vtotal (HEIGHT + VFP + VBP + VS[11:0]),
.vsstart (HEIGHT + VFP),
.vsend (HEIGHT + VFP + VS),
.vsend (HEIGHT + VFP + VS[11:0]),
.vdisp (HEIGHT),
.vmin (vmin),
.vmax (vmax),
@@ -957,11 +957,11 @@ pll_hdmi pll_hdmi
//1920x1080@60 PCLK=148.5MHz CEA
reg [11:0] WIDTH = 1920;
reg [11:0] HFP = 88;
reg [11:0] HS = 48;
reg [12:0] HS = 48;
reg [11:0] HBP = 148;
reg [11:0] HEIGHT = 1080;
reg [11:0] VFP = 4;
reg [11:0] VS = 5;
reg [12:0] VS = 5;
reg [11:0] VBP = 36;
wire [63:0] reconfig_to_pll;
@@ -1214,13 +1214,21 @@ reg hdmi_out_de;
reg [23:0] hdmi_out_d;
always @(posedge hdmi_tx_clk) begin
reg [23:0] hdmi_dv_data;
reg hdmi_dv_hs, hdmi_dv_vs, hdmi_dv_de;
reg hs,vs,de;
reg [23:0] d;
hs <= (~vga_fb & direct_video) ? dv_hs : (direct_video & csync_en) ? hdmi_cs_osd : hdmi_hs_osd;
vs <= (~vga_fb & direct_video) ? dv_vs : hdmi_vs_osd;
de <= (~vga_fb & direct_video) ? dv_de : hdmi_de_osd;
d <= (~vga_fb & direct_video) ? dv_data : hdmi_data_osd;
hdmi_dv_data <= dv_data;
hdmi_dv_hs <= dv_hs;
hdmi_dv_vs <= dv_vs;
hdmi_dv_de <= dv_de;
hs <= (~vga_fb & direct_video) ? hdmi_dv_hs : (direct_video & csync_en) ? hdmi_cs_osd : hdmi_hs_osd;
vs <= (~vga_fb & direct_video) ? hdmi_dv_vs : hdmi_vs_osd;
de <= (~vga_fb & direct_video) ? hdmi_dv_de : hdmi_de_osd;
d <= (~vga_fb & direct_video) ? hdmi_dv_data : hdmi_data_osd;
hdmi_out_hs <= hs;
hdmi_out_vs <= vs;
@@ -1315,11 +1323,11 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
wire cs1 = (vga_fb | vga_scaler) ? vgas_cs : vga_cs;
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : ((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en;
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs);
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18];
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10];
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ;
assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ :((((vga_fb | vga_scaler) ? ~vgas_vs : ~vga_vs) | csync_en) ^ VS[12]);
assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : (((vga_fb | vga_scaler) ? (csync_en ? ~vgas_cs : ~vgas_hs) : (csync_en ? ~vga_cs : ~vga_hs)) ^ HS[12]);
assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[23:18] : vga_o[23:18];
assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[15:10] : vga_o[15:10];
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : (vga_fb | vga_scaler) ? vgas_o[7:2] : vga_o[7:2] ;
`endif
reg video_sync = 0;