From c7f8eea244e938a8ce9dd83599edba8555e89f27 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Fri, 14 May 2010 17:18:17 +0000 Subject: [PATCH] - added byte alignment support for blitter - added constant color blitting 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@911 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/VGA_ctrl/src/tb_vga_frontend64.vhd | 465 +++++++++++++++++++++++-- lib/VGA_ctrl/src/vga_frontend64.vhd | 367 ++++++++++++++----- 2 files changed, 724 insertions(+), 108 deletions(-) diff --git a/lib/VGA_ctrl/src/tb_vga_frontend64.vhd b/lib/VGA_ctrl/src/tb_vga_frontend64.vhd index ac7ec08..b5ddef2 100644 --- a/lib/VGA_ctrl/src/tb_vga_frontend64.vhd +++ b/lib/VGA_ctrl/src/tb_vga_frontend64.vhd @@ -86,6 +86,7 @@ inst_vga_frontend64 : entity work.vga_frontend64 fifo_depth => 2048, fifo_almost_full_thresh => 2048-128, fifo_almost_empty_thresh => 512, + BLIT_CHUNK_SIZE => 512, tsvga => tsvga ) PORT MAP @@ -353,7 +354,26 @@ STIMULUS: process for i in 0 to 99 loop - -- BLIT test + + while(true) loop + -- set blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + wait until rising_edge(CLK_O); + if read_reg(8) = '0' then + exit; + end if; + end loop; + + -- BLIT aligned => aligned test -- Read status CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; @@ -363,7 +383,7 @@ STIMULUS: process wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; wait until rising_edge(CLK_O) and ACK_I = '1'; - -- set src addr first + -- set source start address CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; @@ -372,25 +392,16 @@ STIMULUS: process ADDR_O <= X"0000_0020"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; - -- set src addr last - CYC_O <= '1'; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '1'; - WE_O <= '1'; - SDAT_O <= X"4100_0000" + to_unsigned(4*(80*4-1), 32); - ADDR_O <= X"0000_0024"; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '0'; -- set src dim-x CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= to_unsigned(4*80, 32); + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); ADDR_O <= X"0000_0028"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; - -- set dst addr first + -- set destination start address CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; @@ -399,12 +410,12 @@ STIMULUS: process ADDR_O <= X"0000_0050"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; - -- set dst addr last + -- set constant color CYC_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= X"4200_0000" + to_unsigned(4*(80*4-1), 32); + SDAT_O <= X"0123_4567"; ADDR_O <= X"0000_0054"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; @@ -413,7 +424,7 @@ STIMULUS: process wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= to_unsigned(4*80, 32); + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); ADDR_O <= X"0000_0058"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; @@ -422,7 +433,7 @@ STIMULUS: process wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= to_unsigned(80-1, 32); + SDAT_O <= to_unsigned(256-1, 32); ADDR_O <= X"0000_0060"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; @@ -431,7 +442,7 @@ STIMULUS: process wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= X"0000_0003"; + SDAT_O <= to_unsigned(256-1, 32); ADDR_O <= X"0000_0064"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; @@ -440,16 +451,428 @@ STIMULUS: process wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '1'; WE_O <= '1'; - SDAT_O <= read_reg or X"0000_0100"; + SDAT_O <= (read_reg and not X"0001_0000") or X"0000_0100"; ADDR_O <= X"0000_0000"; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; CYC_O <= '0'; WE_O <= '0'; - wait for 100000*CLK_PERIOD; + + while(true) loop + -- read blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + wait until rising_edge(CLK_O); + if read_reg(8) = '0' then + exit; + end if; + end loop; - + -- BLIT unaligned => aligned test + -- Read status + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + -- set source start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4100_0004"; + ADDR_O <= X"0000_0020"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set src dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0028"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set destination start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4200_0000"; + ADDR_O <= X"0000_0050"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set constant color + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"0123_4567"; + ADDR_O <= X"0000_0054"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set dst dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0058"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set nx + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0060"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set ny + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0064"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= (read_reg and not X"0001_0000") or X"0000_0100"; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + + while(true) loop + -- read blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + wait until rising_edge(CLK_O); + if read_reg(8) = '0' then + exit; + end if; + end loop; + + -- BLIT aligned => unaligned test + -- Read status + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + -- set source start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4100_0000"; + ADDR_O <= X"0000_0020"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set src dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0028"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set destination start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4200_0004"; + ADDR_O <= X"0000_0050"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set constant color + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"0123_4567"; + ADDR_O <= X"0000_0054"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set dst dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0058"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set nx + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0060"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set ny + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0064"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= (read_reg and not X"0001_0000") or X"0000_0100"; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + + while(true) loop + -- read blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + wait until rising_edge(CLK_O); + if read_reg(8) = '0' then + exit; + end if; + end loop; + + -- BLIT const => aligned test + -- Read status + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + -- set source start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4100_0000"; + ADDR_O <= X"0000_0020"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set src dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0028"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set destination start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4200_0000"; + ADDR_O <= X"0000_0050"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set constant color + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"0123_4567"; + ADDR_O <= X"0000_0054"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set dst dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0058"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set nx + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0060"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set ny + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0064"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= read_reg or X"0001_0100"; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + + while(true) loop + -- read blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + wait until rising_edge(CLK_O); + if read_reg(8) = '0' then + exit; + end if; + end loop; + + -- BLIT const => unaligned test + -- Read status + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '0'; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + wait until rising_edge(CLK_O) and ACK_I = '1'; + -- set source start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4100_0000"; + ADDR_O <= X"0000_0020"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set src dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0028"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set destination start address + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"4200_0004"; + ADDR_O <= X"0000_0050"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set constant color + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= X"0123_4567"; + ADDR_O <= X"0000_0054"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set dst dim-x + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(4*tsvga.ts_h.ncyc_scan, 32); + ADDR_O <= X"0000_0058"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set nx + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0060"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set ny + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= to_unsigned(256-1, 32); + ADDR_O <= X"0000_0064"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + -- set blit request + CYC_O <= '1'; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '1'; + WE_O <= '1'; + SDAT_O <= read_reg or X"0001_0100"; + ADDR_O <= X"0000_0000"; + wait until rising_edge(CLK_O) and SRDY_I = '1'; + STB_O <= '0'; + CYC_O <= '0'; + WE_O <= '0'; + + wait for 60000*CLK_PERIOD; + end loop; wait; diff --git a/lib/VGA_ctrl/src/vga_frontend64.vhd b/lib/VGA_ctrl/src/vga_frontend64.vhd index 5ec6ed9..66e6f13 100644 --- a/lib/VGA_ctrl/src/vga_frontend64.vhd +++ b/lib/VGA_ctrl/src/vga_frontend64.vhd @@ -30,6 +30,7 @@ entity vga_frontend64 is fifo_depth : integer := 2048; fifo_almost_full_thresh : natural := 2000; fifo_almost_empty_thresh : natural := 48; + BLIT_CHUNK_SIZE : natural := 512; tsvga : vga_timespec_t := ts_vga_800_600_72 ); Port @@ -154,10 +155,11 @@ architecture Behavioral of vga_frontend64 is signal vga_scan_dma_en2 : std_logic; signal request_cnt_rst : std_logic; signal request_en : std_logic; - signal read_bus_en : std_logic; + signal bus_read_en : std_logic; signal request_cnt : unsigned(28 downto 0); signal read_cnt : unsigned(28 downto 0); signal bus_read_fin : std_logic; + signal bus_cycle_en : std_logic; signal CYC_O_scan : std_logic; signal STB_O_scan : std_logic; @@ -166,18 +168,34 @@ architecture Behavioral of vga_frontend64 is signal front : unsigned(31 downto 0); signal back : unsigned(31 downto 0); - -- Blitter vars - constant BLIT_CHUNK_SIZE : natural := 512; - 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_color_re : std_logic; - signal blitfifo_color_we : std_logic; - signal blitfifo_color_out : unsigned(63 downto 0); - signal blitfifo_color_in : unsigned(63 downto 0); + -- Blitter vars + signal blit_chunk_cnt : natural range 0 to BLIT_CHUNK_SIZE-1; + signal blit_chunk_cnt_rst : std_logic; + signal blit_chunk_cnt_en : std_logic; + + -- Source Blitter FIFO signals + signal blitfifo_src_full : std_logic; + signal blitfifo_src_empty : std_logic; + signal blitfifo_src_re : std_logic; + signal blitfifo_src_we : std_logic; + signal blitfifo_src_out : unsigned(63 downto 0); + signal blitfifo_src_in : unsigned(63 downto 0); + + -- Source alignment register + signal blit_src_addr : unsigned(2 downto 0); + signal blit_src_reg_vld : std_logic; + signal blit_src_reg : unsigned(63 downto 0); + signal blit_src_reg_be : unsigned(7 downto 0); + signal blit_src_rdy : std_logic; + signal blit_src_we : std_logic; + signal blit_src_re : std_logic; + signal blit_src_unaligned : std_logic; + signal blit_src_do_extra : std_logic; + signal blit_src_do_extra2 : std_logic; + + signal blit_src_row_cnt : unsigned(31 downto 0); + signal blit_src_last_in_row : std_logic; signal blit_src_cnt_x : unsigned(31 downto 0); signal blit_src_cnt_y : unsigned(31 downto 0); signal blit_src_off_y : unsigned(31 downto 0); @@ -187,11 +205,28 @@ architecture Behavioral of vga_frontend64 is signal STB_O_blit_src : std_logic; signal ADDR_O_blit_src : unsigned(31 downto 0); + -- Destination alignment register + signal blit_dst_reg : unsigned(63 downto 0); + signal blit_dst_reg_vld : std_logic; + signal blit_dst_unaligned : std_logic; + signal blit_dst_row_cnt : unsigned(31 downto 0); + signal blit_dst_last_in_row : std_logic; + signal blit_dst_do_extra : std_logic; + signal blit_dst_reg_be : unsigned(7 downto 0); + signal blit_dst_rdy : std_logic; + signal blit_dst_we : std_logic; + signal blit_dst_re : std_logic; signal blit_dst_cnt_x : unsigned(31 downto 0); signal blit_dst_cnt_y : unsigned(31 downto 0); signal blit_dst_off_y : unsigned(31 downto 0); signal blit_dst_offset : unsigned(31 downto 0); signal blit_dst_finish : std_logic; + + signal blit_const_color : unsigned(31 downto 0); + signal blit_const_color_en : std_logic; + signal blit_const_color_vld : std_logic; + + signal CYC_O_blit_dst : std_logic; signal STB_O_blit_dst : std_logic; signal ADDR_O_blit_dst : unsigned(31 downto 0); @@ -205,7 +240,7 @@ architecture Behavioral of vga_frontend64 is signal bus_fifo_we : std_logic; signal bus_fifo_full : std_logic; signal bus_fifo_empty : std_logic; - signal bus_rdy : std_logic; + signal bus_fifo_rdy : std_logic; alias bus_fifo_addr_in is bus_fifo_din(31 downto 0); alias bus_fifo_data_in is bus_fifo_din(95 downto 32); @@ -217,12 +252,11 @@ 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, 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_prime_pipe, blit_dst_bus_request, bus_fin); signal s, sn : vm_state_t; begin - proc_synced_vga_scan_en: process(CLK_I) begin @@ -257,7 +291,7 @@ proc_blit_request_flags: blit_request <= '0'; elsif blit_request_set = '1' then blit_request <= '1'; - elsif blit_dst_finish = '1' and blitfifo_empty = '1' then + elsif blit_dst_finish = '1' then blit_request <= '0'; end if; end if; @@ -269,7 +303,7 @@ proc_blit_complete_flag: if rising_edge(CLK_I) 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' and blit_request = '1' then + elsif blit_dst_finish = '1' and blit_request = '1' then blit_complete <= '1'; end if; end if; @@ -361,32 +395,7 @@ inst_linefifo: entity work.fifo_async fifo_color_in <= MDAT_I; fifo_color_re <= stat_scan and odd_pixel(0); - fifo_color_we <= ACK_I and read_bus_en and CYC_O_scan; -- TODO: - -inst_blitfifo: entity work.fifo_sync - GENERIC MAP - ( - addr_width => NextExpBaseTwo(BLIT_CHUNK_SIZE), - data_width => 64 - ) - PORT MAP - ( - rst => blit_reset, - clk => CLK_I, - we => blitfifo_color_we, - re => blitfifo_color_re, - data_w => blitfifo_color_in, - data_r => blitfifo_color_out, - fifo_full => blitfifo_full, - fifo_empty => blitfifo_empty, - fifo_afull => open, - fifo_aempty => open - - ); - - blitfifo_color_in <= MDAT_I; - 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: + fifo_color_we <= ACK_I and CYC_O_scan; -- TODO: -- Instantiate synchronous FIFO inst_bus_fifo: entity work.fifo_sync @@ -409,17 +418,16 @@ inst_bus_fifo: entity work.fifo_sync data_w => bus_fifo_din, data_r => bus_fifo_dout ); - bus_rdy <= not bus_fifo_full; + bus_fifo_rdy <= not bus_fifo_full; bus_fifo_re <= not bus_fifo_empty and SRDY_I; - 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_we <= bus_cycle_en and (STB_O_scan or STB_O_blit_src or STB_O_blit_dst); + bus_fifo_data_in <= blit_dst_reg; 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_sel_in <= blit_dst_reg_be when CYC_O_blit_dst = '1' else (others => '1'); bus_fifo_we_in <= CYC_O_blit_dst; - - CYC_O <= CYC_O_scan or CYC_O_blit_src or CYC_O_blit_dst; + CYC_O <= bus_cycle_en; vga_master_next: process(CLK_I) @@ -434,7 +442,7 @@ vga_master_next: end process; vga_master: - 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) + process(s, stat_vga_rdy, vga_scan_dma_en2, fifo_almost_empty, fifo_almost_full, SRDY_I, ACK_I, bus_read_fin, bus_fifo_rdy, bus_fifo_empty, blit_chunk_cnt, blitfifo_src_empty, blit_dst_reg_vld, blit_src_finish, blit_dst_finish, blit_const_color_en, blitfifo_src_full) begin CYC_O_scan <= '0'; @@ -445,9 +453,13 @@ vga_master: STB_O_blit_dst <= '0'; request_cnt_rst <= '0'; request_en <= '0'; - read_bus_en <= '0'; - sn <= s; + bus_read_en <= '0'; + bus_cycle_en <= '0'; + blit_chunk_cnt_rst <= '0'; + blit_chunk_cnt_en <= '0'; + + sn <= s; case s is when init => if stat_vga_rdy = '1' then @@ -456,58 +468,74 @@ vga_master: when rdy => request_cnt_rst <= '1'; + blit_chunk_cnt_rst <= '1'; 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 + elsif blit_request = '1' then -- ToDo: richtig prüfen anhand eines states wer dran ist. Nicht auf FIFO state prüfen + if blitfifo_src_empty = '0' or blit_dst_reg_vld = '1' then + sn <= blit_dst_prime_pipe; + elsif blit_const_color_en = '0' then sn <= blit_src_bus_request; - else - sn <= blit_dst_bus_request; end if; end if; when scan_bus_request => + bus_cycle_en <= '1'; CYC_O_scan <= '1'; STB_O_scan <= '1'; request_en <= '1'; - read_bus_en <= '1'; + bus_read_en <= '1'; if fifo_almost_full = '1' then sn <= scan_bus_read; end if; when scan_bus_read => - CYC_O_scan <= '1'; - read_bus_en <= '1'; + bus_cycle_en <= '1'; + CYC_O_scan <= '1'; + bus_read_en <= '1'; if bus_read_fin = '1' then sn <= rdy; end if; when blit_src_bus_request => + bus_cycle_en <= '1'; CYC_O_blit_src <= '1'; STB_O_blit_src <= '1'; request_en <= '1'; - read_bus_en <= '1'; + bus_read_en <= '1'; + blit_chunk_cnt_en <= '1'; if blit_chunk_cnt = 0 or blit_src_finish = '1' then sn <= blit_src_bus_read; end if; when blit_src_bus_read => + bus_cycle_en <= '1'; CYC_O_blit_src <= '1'; - read_bus_en <= '1'; + bus_read_en <= '1'; if bus_read_fin = '1' then sn <= rdy; end if; + when blit_dst_prime_pipe => + bus_cycle_en <= '1'; + CYC_O_blit_dst <= '1'; + STB_O_blit_dst <= blit_dst_reg_vld; + blit_chunk_cnt_en <= blit_dst_reg_vld; + if blit_dst_reg_vld = '1' then + sn <= blit_dst_bus_request; + end if; + when blit_dst_bus_request => + bus_cycle_en <= '1'; CYC_O_blit_dst <= '1'; - STB_O_blit_dst <= '1'; - if blitfifo_empty = '1' then - STB_O_blit_dst <= '0'; - sn <= blit_dst_bus_fin; + STB_O_blit_dst <= blit_dst_reg_vld; + blit_chunk_cnt_en <= blit_dst_reg_vld; + if blit_chunk_cnt = 0 or blit_dst_reg_vld = '0' then + sn <= bus_fin; end if; - when blit_dst_bus_fin => - CYC_O_blit_dst <= '1'; + when bus_fin => + bus_cycle_en <= '1'; if bus_fifo_empty = '1' then sn <= rdy; end if; @@ -524,7 +552,7 @@ proc_bus_request_counter: if rising_edge(CLK_I) then if request_cnt_rst = '1' then request_cnt <= (others => '0'); - elsif request_en = '1' and bus_rdy = '1' then + elsif request_en = '1' and bus_fifo_rdy = '1' then request_cnt <= request_cnt + 1; end if; end if; @@ -536,7 +564,7 @@ proc_bus_read_counter: if rising_edge(CLK_I) then if request_cnt_rst = '1' then read_cnt <= (others => '0'); - elsif read_bus_en = '1' and ACK_I = '1' then + elsif bus_read_en = '1' and ACK_I = '1' then read_cnt <= read_cnt + 1; end if; end if; @@ -557,16 +585,17 @@ 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 + if blit_chunk_cnt_rst = '1' then + blit_chunk_cnt <= BLIT_CHUNK_SIZE-1; + elsif blit_chunk_cnt_en = '1' and bus_fifo_rdy = '1' then + if blit_chunk_cnt /= 0 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"); @@ -579,7 +608,7 @@ proc_scan_addr: if vga_scan_dma_en2 = '0' then pixel_cnt <= 0; front <= host_fb_front; - elsif STB_O_scan = '1' and bus_rdy = '1' then + elsif STB_O_scan = '1' and bus_fifo_rdy = '1' then if pixel_cnt /= MAX_REQUEST_CNT/2-1 then pixel_cnt <= pixel_cnt + 1; else @@ -593,7 +622,95 @@ proc_scan_addr: end if; end process; - ADDR_O_blit_src <= blit_addr_src_0 + blit_src_offset; +--------------------------------------------------------------------------------- +inst_align_src : entity work.align + GENERIC MAP + ( + data_width => 64, + aggregate_size => 8, + allow_partial_valid => true + ) + PORT MAP + ( + rst => blit_reset, + clk => CLK_I, + ce => blit_src_re, + eb => '1', + offset => blit_src_addr, + din_last_vld => '0', + din_vld => blit_src_we, + din => MDAT_I, + dout_vld => blit_src_reg_vld, + dout => blit_src_reg, + dout_be => blit_src_reg_be + + ); + + blit_src_we <= ACK_I and CYC_O_blit_src; -- TODO: + blit_src_re <= not blitfifo_src_full; -- TODO: + +proc_blit_src_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if blit_reset = '1' then + blit_src_row_cnt <= (others => '0'); + blit_src_unaligned <= '0'; + blit_src_last_in_row <= '0'; + if blit_src_addr (2 downto 0) /= "000" then + blit_src_unaligned <= not blit_const_color_en; + blit_src_last_in_row <= '1'; + end if; + blit_src_do_extra2 <= '0'; + elsif blit_src_reg_vld = '1' then + if blit_src_re = '1' then + blit_src_last_in_row <= '0'; + if blit_src_last_in_row = '0' then + if blit_src_row_cnt /= blit_nx then + blit_src_row_cnt <= blit_src_row_cnt + 1; + if blit_src_unaligned = '1' then + blit_src_do_extra2 <= '1'; + end if; + elsif blit_src_do_extra2 = '1' then + blit_src_do_extra2 <= '0'; + else + blit_src_row_cnt <= (others => '0'); + blit_src_last_in_row <= blit_src_unaligned; + end if; + end if; + end if; + end if; + end if; + end process; + +inst_blitfifo_src: entity work.fifo_sync + GENERIC MAP + ( + addr_width => NextExpBaseTwo(BLIT_CHUNK_SIZE), + data_width => blitfifo_src_in'length + ) + PORT MAP + ( + rst => blit_reset, + clk => CLK_I, + we => blitfifo_src_we, + re => blitfifo_src_re, + data_w => blitfifo_src_in, + data_r => blitfifo_src_out, + fifo_full => blitfifo_src_full, + fifo_empty => blitfifo_src_empty, + fifo_afull => open, + fifo_aempty => open + + ); + + blitfifo_src_we <= (blit_src_reg_vld and not blit_src_last_in_row) when blit_const_color_en = '0' else (blit_request and not blit_src_finish); + blitfifo_src_in <= blit_src_reg when blit_const_color_en = '0' else (blit_const_color & blit_const_color); + blitfifo_src_re <= blit_dst_re and not blit_dst_last_in_row; + +--------------------------------------------------------------------------------- + ADDR_O_blit_src <= blit_addr_src_0(31 downto 3) & "000" + blit_src_offset; + blit_src_addr <= blit_addr_src_0(2 downto 0); proc_blit_addr_src: process(CLK_I) @@ -605,43 +722,108 @@ proc_blit_addr_src: blit_src_offset <= (others => '0'); blit_src_off_y <= blit_dimx_src_0; blit_src_finish <= '0'; - elsif STB_O_blit_src = '1' and bus_rdy = '1' then + blit_src_do_extra <= '0'; + elsif blit_src_finish = '0' and ((STB_O_blit_src = '1' and bus_fifo_rdy = '1') or (blit_const_color_en = '1' and blitfifo_src_full = '0')) then + blit_src_offset <= blit_src_offset + 8; if blit_src_cnt_x /= blit_nx then blit_src_cnt_x <= blit_src_cnt_x + 1; - blit_src_offset <= blit_src_offset + 8; + if blit_src_unaligned = '1' then + blit_src_do_extra <= '1'; + end if; + elsif blit_src_do_extra = '1' then + blit_src_do_extra <= '0'; else if blit_src_cnt_y /= blit_ny then - blit_src_cnt_x <= (others => '0'); + blit_src_cnt_x <= (others => '0'); blit_src_offset <= blit_src_off_y; blit_src_cnt_y <= blit_src_cnt_y + 1; blit_src_off_y <= blit_src_off_y + blit_dimx_src_0; else blit_src_finish <= '1'; - end if; + end if; end if; end if; end if; end process; - ADDR_O_blit_dst <= blit_addr_dst + blit_dst_offset; +--------------------------------------------------------------------------------- +inst_align_dst : entity work.align + GENERIC MAP + ( + data_width => 64, + aggregate_size => 8, + allow_partial_valid => true + ) + PORT MAP + ( + rst => blit_reset, + clk => CLK_I, + eb => '1', + ce => blit_dst_re, + offset => blit_addr_dst(2 downto 0), + din_last_vld => blit_dst_last_in_row, + din_vld => blit_dst_we, + din => blitfifo_src_out, + dout_vld => blit_dst_reg_vld, + dout => blit_dst_reg, + dout_be => blit_dst_reg_be + + ); + + blit_dst_we <= not blitfifo_src_empty and not blit_dst_last_in_row; + blit_dst_re <= CYC_O_blit_dst and bus_fifo_rdy; + +proc_blit_dst_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if blit_reset = '1' then + blit_dst_last_in_row <= '0'; + blit_dst_unaligned <= '0'; + if blit_addr_dst (2 downto 0) /= "000" then + blit_dst_unaligned <= '1'; + end if; + blit_dst_row_cnt <= (others => '0'); + elsif blit_dst_re = '1' then + blit_dst_last_in_row <= '0'; + if blit_dst_we = '1' then + if blit_dst_row_cnt /= blit_nx then + blit_dst_row_cnt <= blit_dst_row_cnt + 1; + else + blit_dst_row_cnt <= (others => '0'); + blit_dst_last_in_row <= blit_dst_unaligned; + end if; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------------- + ADDR_O_blit_dst <= blit_addr_dst(31 downto 3) & "000" + blit_dst_offset; proc_blit_addr_dst: process(CLK_I) begin if rising_edge(CLK_I) then if blit_reset = '1' then - blit_dst_cnt_x <= (others => '0'); blit_dst_cnt_y <= (others => '0'); blit_dst_offset <= (others => '0'); blit_dst_off_y <= blit_dimx_dst; blit_dst_finish <= '0'; - elsif STB_O_blit_dst = '1' and bus_rdy = '1' then + blit_dst_cnt_x <= (others => '0'); + blit_dst_do_extra <= '0'; + elsif blit_dst_finish = '0' and (STB_O_blit_dst = '1' and bus_fifo_rdy = '1') then + blit_dst_offset <= blit_dst_offset + 8; if blit_dst_cnt_x /= blit_nx then blit_dst_cnt_x <= blit_dst_cnt_x + 1; - blit_dst_offset <= blit_dst_offset + 8; + if blit_dst_unaligned = '1' then + blit_dst_do_extra <= '1'; + end if; + elsif blit_dst_do_extra = '1' then + blit_dst_do_extra <= '0'; else if blit_dst_cnt_y /= blit_ny then - blit_dst_cnt_x <= (others => '0'); + blit_dst_cnt_x <= (others => '0'); blit_dst_offset <= blit_dst_off_y; blit_dst_cnt_y <= blit_dst_cnt_y + 1; blit_dst_off_y <= blit_dst_off_y + blit_dimx_dst; @@ -653,6 +835,7 @@ proc_blit_addr_dst: end if; end process; +--------------------------------------------------------------------------------- inst_char_gen : entity work.char_gen GENERIC MAP ( @@ -794,6 +977,8 @@ registers_read: end if; end process; + blit_const_color_en <= blit_func_sel(0); + registers_write: process(CLK_I) begin @@ -815,6 +1000,9 @@ registers_write: blit_comb_sel <= (others => '0'); host_fb_front <= X"40000000"; host_fb_back <= X"40010000"; + blit_addr_src_0 <= X"40000000"; + blit_addr_src_1 <= X"40020000"; + blit_addr_dst <= X"40040000"; cg_color <= (X"FF", X"FF", X"FF", X"FF"); elsif (STB_I and CYC_I and WE_I) = '1' then case ADDR_I(6 downto 2) is @@ -870,7 +1058,7 @@ registers_write: -- sys_blit_descr_src_0 -- 0x20 when "01000" => - blit_addr_src_0 <= SDAT_I(31 downto 3) & "000"; + blit_addr_src_0 <= SDAT_I(31 downto 0); -- 0x28 when "01010" => @@ -879,7 +1067,7 @@ registers_write: -- sys_blit_descr_src_1 -- 0x30 when "01100" => - blit_addr_src_1 <= SDAT_I(31 downto 3) & "000"; + blit_addr_src_1 <= SDAT_I(31 downto 0); -- 0x38 when "01110" => @@ -888,7 +1076,12 @@ registers_write: -- sys_blit_descr_dst -- 0x50 when "10100" => - blit_addr_dst <= SDAT_I(31 downto 3) & "000"; + blit_addr_dst <= SDAT_I(31 downto 0); + + -- sys_blit_const_color + -- 0x54 + when "10101" => + blit_const_color <= SDAT_I(31 downto 0); -- 0x58 when "10110" =>