From fc1a9e7b3d1e3deadb36dce332131c1d881dccc6 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 22 Nov 2009 22:35:55 +0000 Subject: [PATCH] - blitter FIFO is reseted on every new request - blitter always avaliable regardless of MSTEN - blit writes finish on blit_fifo_empty. Chunk counter only used for reads - premature finish of blit reads if NX*NY satisfied. No more chunk granularity - set BLIT_CHUNK_SIZE to 128 double-pixels Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@676 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/VGA_ctrl/src/vga_frontend64.vhd | 114 ++++++++++++++-------------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/lib/VGA_ctrl/src/vga_frontend64.vhd b/lib/VGA_ctrl/src/vga_frontend64.vhd index 019dae3..8f96578 100644 --- a/lib/VGA_ctrl/src/vga_frontend64.vhd +++ b/lib/VGA_ctrl/src/vga_frontend64.vhd @@ -148,11 +148,12 @@ architecture Behavioral of vga_frontend64 is signal blit_complete : std_logic; signal blit_complete_ack : std_logic; signal blit_complete_inten : std_logic; + signal blit_reset : std_logic; signal vga_scan_rdy : std_logic; - signal vga_master_en : std_logic; + signal vga_scan_dma_en : std_logic; + signal vga_scan_dma_en2 : std_logic; signal request_cnt_rst : std_logic; signal request_en : std_logic; - signal pixel_cnt_rst : std_logic; signal read_bus_en : std_logic; signal request_cnt : unsigned(28 downto 0); signal read_cnt : unsigned(28 downto 0); @@ -166,14 +167,12 @@ architecture Behavioral of vga_frontend64 is signal back : unsigned(31 downto 0); -- Blitter vars - constant BLIT_CHUNK_SIZE : natural := 32; + constant BLIT_CHUNK_SIZE : natural := 128; signal blit_chunk_cnt : natural range 0 to BLIT_CHUNK_SIZE-1; -- Blitter FIFO signals signal blitfifo_full : std_logic; signal blitfifo_empty : std_logic; - signal blitfifo_almost_empty : std_logic; - signal blitfifo_almost_full : std_logic; signal blitfifo_color_re : std_logic; signal blitfifo_color_we : std_logic; signal blitfifo_color_out : unsigned(63 downto 0); @@ -218,17 +217,29 @@ architecture Behavioral of vga_frontend64 is alias bus_fifo_sel_out is bus_fifo_dout(103 downto 96); alias bus_fifo_we_out is bus_fifo_dout(104); - type vm_state_t is (init, idle, rdy, scan_bus_request, scan_bus_read, blit_src_bus_request, blit_src_bus_read, blit_dst_bus_request, blit_dst_bus_fin); + type vm_state_t is (init, rdy, scan_bus_request, scan_bus_read, blit_src_bus_request, blit_src_bus_read, blit_dst_bus_request, blit_dst_bus_fin); signal s, sn : vm_state_t; begin +proc_synced_vga_scan_en: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + vga_scan_dma_en2 <= '0'; + elsif vga_scan_rdy = '1' then + vga_scan_dma_en2 <= vga_scan_dma_en; + end if; + end if; + end process; + proc_bufchg_irq: process(CLK_I) begin if rising_edge(CLK_I) then - if pixel_cnt_rst = '1' or bufchg_flag_ack = '1' then + if vga_scan_dma_en2 = '0' or bufchg_flag_ack = '1' then bufchg_flag <= '0'; elsif bufchg = '1' then bufchg_flag <= '1'; @@ -242,7 +253,7 @@ proc_blit_request_flags: process(CLK_I) begin if rising_edge(CLK_I) then - if pixel_cnt_rst = '1' then + if RST_I = '1' then blit_request <= '0'; elsif blit_request = '0' then if blit_request_set = '1' then @@ -258,7 +269,7 @@ proc_blit_complete_flag: process(CLK_I) begin if rising_edge(CLK_I) then - if pixel_cnt_rst = '1' or blit_request_set = '1' or blit_complete_ack = '1' then + if RST_I = '1' or blit_request_set = '1' or blit_complete_ack = '1' then blit_complete <= '0'; elsif blit_dst_finish = '1' and blitfifo_empty = '1' then blit_complete <= '1'; @@ -357,14 +368,12 @@ inst_linefifo: entity work.fifo_async inst_blitfifo: entity work.fifo_sync GENERIC MAP ( - addr_width => NextExpBaseTwo(32), - data_width => 64, - almost_full_thresh => 24, - almost_empty_thresh => 8 + addr_width => NextExpBaseTwo(BLIT_CHUNK_SIZE), + data_width => 64 ) PORT MAP ( - rst => RST_I, + rst => blit_reset, clk => CLK_I, we => blitfifo_color_we, re => blitfifo_color_re, @@ -372,13 +381,13 @@ inst_blitfifo: entity work.fifo_sync data_r => blitfifo_color_out, fifo_full => blitfifo_full, fifo_empty => blitfifo_empty, - fifo_afull => blitfifo_almost_full, - fifo_aempty => blitfifo_almost_empty + fifo_afull => open, + fifo_aempty => open ); blitfifo_color_in <= MDAT_I; - blitfifo_color_re <= CYC_O_blit_dst and bus_rdy; + blitfifo_color_re <= STB_O_blit_dst and bus_rdy; blitfifo_color_we <= ACK_I and read_bus_en and CYC_O_blit_src; -- TODO: -- Instantiate synchronous FIFO @@ -403,14 +412,13 @@ inst_bus_fifo: entity work.fifo_sync ); bus_rdy <= not bus_fifo_full; bus_fifo_re <= not bus_fifo_empty and SRDY_I; - bus_fifo_we <= request_en; + bus_fifo_we <= STB_O_scan or STB_O_blit_src or STB_O_blit_dst; bus_fifo_data_in <= blitfifo_color_out; bus_fifo_addr_in <= ADDR_O_blit_src when CYC_O_blit_src = '1' else ADDR_O_blit_dst when CYC_O_blit_dst = '1' else ADDR_O_scan; bus_fifo_sel_in <= (others => '1'); bus_fifo_we_in <= CYC_O_blit_dst; - ADDR_O_scan <= front + (to_unsigned(pixel_cnt, 29) & "000"); CYC_O <= CYC_O_scan or CYC_O_blit_src or CYC_O_blit_dst; @@ -427,7 +435,7 @@ vga_master_next: end process; vga_master: - process(s, stat_vga_rdy, vga_master_en, vga_scan_rdy, fifo_almost_empty, fifo_almost_full, SRDY_I, ACK_I, bus_read_fin, bus_fifo_empty, blit_chunk_cnt) + process(s, stat_vga_rdy, vga_scan_dma_en2, fifo_almost_empty, fifo_almost_full, SRDY_I, ACK_I, bus_read_fin, bus_fifo_empty, blit_chunk_cnt, blitfifo_empty, blit_src_finish) begin CYC_O_scan <= '0'; @@ -436,7 +444,6 @@ vga_master: STB_O_blit_src <= '0'; CYC_O_blit_dst <= '0'; STB_O_blit_dst <= '0'; - pixel_cnt_rst <= '0'; request_cnt_rst <= '0'; request_en <= '0'; read_bus_en <= '0'; @@ -445,18 +452,12 @@ vga_master: case s is when init => if stat_vga_rdy = '1' then - sn <= idle; - end if; - - when idle => - pixel_cnt_rst <= '1'; - if vga_master_en = '1' and vga_scan_rdy = '1' then sn <= rdy; end if; when rdy => request_cnt_rst <= '1'; - if fifo_almost_empty = '1' then + if fifo_almost_empty = '1' and vga_scan_dma_en2 = '1' then sn <= scan_bus_request; elsif blit_request = '1' then if blitfifo_empty = '1' then @@ -480,9 +481,6 @@ vga_master: read_bus_en <= '1'; if bus_read_fin = '1' then sn <= rdy; - if vga_master_en = '0' then - sn <= idle; - end if; end if; when blit_src_bus_request => @@ -490,8 +488,8 @@ vga_master: STB_O_blit_src <= '1'; request_en <= '1'; read_bus_en <= '1'; - if blit_chunk_cnt = 0 then - sn <= blit_src_bus_read; + if blit_chunk_cnt = 0 or blit_src_finish = '1' then + sn <= blit_src_bus_read; end if; when blit_src_bus_read => @@ -504,9 +502,9 @@ vga_master: when blit_dst_bus_request => CYC_O_blit_dst <= '1'; STB_O_blit_dst <= '1'; - request_en <= '1'; - if blit_chunk_cnt = 0 then - sn <= blit_dst_bus_fin; + if blitfifo_empty = '1' then + STB_O_blit_dst <= '0'; + sn <= blit_dst_bus_fin; end if; when blit_dst_bus_fin => @@ -516,7 +514,7 @@ vga_master: end if; when others => - sn <= idle; + sn <= rdy; end case; end process; @@ -556,12 +554,30 @@ proc_bus_read_finish: end if; end process; +proc_blit_chunk_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if STB_O_blit_src = '1' then + if blit_chunk_cnt /= 0 and bus_rdy = '1' then + blit_chunk_cnt <= blit_chunk_cnt - 1; + end if; + else + blit_chunk_cnt <= BLIT_CHUNK_SIZE-1; + end if; + end if; + end process; + + blit_reset <= RST_I or (blit_request_set and not blit_request); + + ADDR_O_scan <= front + (to_unsigned(pixel_cnt, 29) & "000"); + proc_scan_addr: process(CLK_I) begin if rising_edge(CLK_I) then bufchg <= '0'; - if pixel_cnt_rst = '1' then + if vga_scan_dma_en2 = '0' then pixel_cnt <= 0; front <= host_fb_front; elsif STB_O_scan = '1' and bus_rdy = '1' then @@ -580,23 +596,11 @@ proc_scan_addr: ADDR_O_blit_src <= blit_addr_src_0 + blit_src_offset; -proc_blit_chunk_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if request_en = '0' then - blit_chunk_cnt <= BLIT_CHUNK_SIZE-1; - elsif blit_chunk_cnt /= 0 and bus_rdy = '1' and (STB_O_blit_src = '1' or STB_O_blit_dst = '1') then - blit_chunk_cnt <= blit_chunk_cnt - 1; - end if; - end if; - end process; - proc_blit_addr_src: process(CLK_I) begin if rising_edge(CLK_I) then - if RST_I = '1' or (blit_request_set and not blit_request) = '1' then + if blit_reset = '1' then blit_src_cnt_x <= (others => '0'); blit_src_cnt_y <= (others => '0'); blit_src_offset <= (others => '0'); @@ -626,7 +630,7 @@ proc_blit_addr_dst: process(CLK_I) begin if rising_edge(CLK_I) then - if RST_I = '1' or (blit_request_set and not blit_request) = '1' then + if blit_reset = '1' then blit_dst_cnt_x <= (others => '0'); blit_dst_cnt_y <= (others => '0'); blit_dst_offset <= (others => '0'); @@ -703,7 +707,7 @@ registers_read: -- sys_vga_ctrl 0 when "0000" => SDAT_O(0) <= cg_rdy; - SDAT_O(1) <= vga_master_en; + SDAT_O(1) <= vga_scan_dma_en; SDAT_O(2) <= bufchg_irq_en; SDAT_O(3) <= bufchg_flag; SDAT_O(8) <= blit_request; @@ -792,7 +796,7 @@ registers_write: blit_complete_ack <= '0'; if RST_I = '1' then cg_din <= (others => '0'); - vga_master_en <= '0'; + vga_scan_dma_en <= '0'; bufchg_irq_en <= '0'; blit_complete_inten <= '0'; blit_func_sel <= (others => '0'); @@ -805,7 +809,7 @@ registers_write: -- sys_vga_ctrl 0 when "0000" => - vga_master_en <= SDAT_I(1); + vga_scan_dma_en <= SDAT_I(1); bufchg_irq_en <= SDAT_I(2); bufchg_flag_ack <= SDAT_I(3); cg_clr_screen <= SDAT_I(4);