From 94f8cd36ec22a5b9ebc5fb291e2df11d3e70918d Mon Sep 17 00:00:00 2001 From: Sorgelig Date: Sat, 26 Mar 2022 21:34:40 +0800 Subject: [PATCH] Update sys. --- files.qip | 2 +- sys/arcade_video.v | 3 + sys/ascal.vhd | 305 ++++++++++++++++++++++----------------------- sys/hps_io.sv | 78 +++++++----- sys/sys_top.v | 64 +++++----- 5 files changed, 238 insertions(+), 214 deletions(-) diff --git a/files.qip b/files.qip index b13ef91..174ff39 100644 --- a/files.qip +++ b/files.qip @@ -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 diff --git a/sys/arcade_video.v b/sys/arcade_video.v index e0d0789..f53b136 100644 --- a/sys/arcade_video.v +++ b/sys/arcade_video.v @@ -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 diff --git a/sys/ascal.vhd b/sys/ascal.vhd index afb3d16..aa2af61 100644 --- a/sys/ascal.vhd +++ b/sys/ascal.vhd @@ -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 diff --git a/sys/hps_io.sv b/sys/hps_io.sv index 6b2b94f..864f1bd 100644 --- a/sys/hps_io.sv +++ b/sys/hps_io.sv @@ -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]; diff --git a/sys/sys_top.v b/sys/sys_top.v index 37b2a39..635ae56 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -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;