fixed unaligned src blitter bug

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@913 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2010-05-15 15:05:35 +00:00
parent 5c37f43fcb
commit dff1254bd9
+88 -61
View File
@@ -195,7 +195,8 @@ architecture Behavioral of vga_frontend64 is
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_first : std_logic;
signal blit_src_last : 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);
@@ -210,12 +211,14 @@ architecture Behavioral of vga_frontend64 is
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_first : std_logic;
signal blit_dst_last : 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_vld : 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);
@@ -255,6 +258,39 @@ architecture Behavioral of vga_frontend64 is
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;
type byte_en_rom_t is array (0 to 2*8-1) of unsigned (8-1 downto 0);
function gen_byte_en_rom(N : natural) return byte_en_rom_t is
variable k : integer;
variable result : byte_en_rom_t;
begin
k:=0;
result(k) := (others => '1');
k := k + 1;
for i in 1 to N-1 loop
result(k) := (N-1 downto i => '1') & (i-1 downto 0 => '0');
k := k + 1;
end loop;
result(k) := (others => '1');
k := k + 1;
for i in 1 to N-1 loop
result(k) := (N-1 downto i => '0') & (i-1 downto 0 => '1');
k := k + 1;
end loop;
return result;
end gen_byte_en_rom;
signal byte_en_rom : byte_en_rom_t := gen_byte_en_rom(8);
signal byte_en : unsigned (8-1 downto 0);
signal eb : std_logic;
--------------------------------------------------------------------------
begin
proc_synced_vga_scan_en:
@@ -442,7 +478,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_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)
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_vld, blit_src_finish, blit_dst_finish, blit_const_color_en, blitfifo_src_full)
begin
CYC_O_scan <= '0';
@@ -472,7 +508,7 @@ vga_master:
if fifo_almost_empty = '1' and vga_scan_dma_en2 = '1' then
sn <= scan_bus_request;
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
if blitfifo_src_empty = '0' or blit_dst_vld = '1' then
sn <= blit_dst_prime_pipe;
elsif blit_const_color_en = '0' then
sn <= blit_src_bus_request;
@@ -519,18 +555,18 @@ vga_master:
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
STB_O_blit_dst <= blit_dst_vld;
blit_chunk_cnt_en <= blit_dst_vld;
if blit_dst_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 <= blit_dst_reg_vld;
blit_chunk_cnt_en <= blit_dst_reg_vld;
if blit_chunk_cnt = 0 or blit_dst_reg_vld = '0' then
STB_O_blit_dst <= blit_dst_vld;
blit_chunk_cnt_en <= blit_dst_vld;
if blit_chunk_cnt = 0 or blit_dst_vld = '0' then
sn <= bus_fin;
end if;
@@ -656,27 +692,27 @@ proc_blit_src_counter:
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_first <= '0';
blit_src_last <= '0';
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;
if blit_src_addr (2 downto 0) /= "000" then
blit_src_unaligned <= not blit_const_color_en;
blit_src_first <= not blit_const_color_en;
blit_src_do_extra2 <= not blit_const_color_en;
end if;
elsif blit_src_re = '1' then
if blit_src_reg_vld = '1' then
blit_src_first <= '0';
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_first <= blit_src_unaligned;
end if;
end if;
end if;
@@ -704,9 +740,9 @@ inst_blitfifo_src: entity work.fifo_sync
);
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_we <= (blit_src_reg_vld and not blit_src_first) 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;
blitfifo_src_re <= blit_dst_re;
---------------------------------------------------------------------------------
ADDR_O_blit_src <= blit_addr_src_0(31 downto 3) & "000" + blit_src_offset;
@@ -761,43 +797,25 @@ inst_align_dst : entity work.align
eb => '1',
ce => blit_dst_re,
offset => blit_addr_dst(2 downto 0),
din_last_vld => blit_dst_last_in_row,
din_last_vld => '0',
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
dout_be => open
);
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;
eb <= '1';
blit_dst_reg_be <= byte_en_rom(to_integer(not eb & blit_addr_dst(2 downto 0))) when blit_dst_first = '1' else
not byte_en_rom(to_integer(not eb & blit_addr_dst(2 downto 0))) when blit_dst_last = '1' else
(others => '1');
blit_dst_we <= not blitfifo_src_empty;
blit_dst_re <= CYC_O_blit_dst and bus_fifo_rdy and not blit_dst_last;
blit_dst_vld <= blit_dst_reg_vld or blit_dst_last;
---------------------------------------------------------------------------------
ADDR_O_blit_dst <= blit_addr_dst(31 downto 3) & "000" + blit_dst_offset;
@@ -812,8 +830,16 @@ proc_blit_addr_dst:
blit_dst_finish <= '0';
blit_dst_cnt_x <= (others => '0');
blit_dst_do_extra <= '0';
blit_dst_first <= '1';
blit_dst_last <= '0';
blit_dst_unaligned <= '0';
if blit_addr_dst (2 downto 0) /= "000" then
blit_dst_unaligned <= '1';
end if;
elsif blit_dst_finish = '0' and (STB_O_blit_dst = '1' and bus_fifo_rdy = '1') then
blit_dst_offset <= blit_dst_offset + 8;
blit_dst_first <= blit_dst_last;
blit_dst_last <= '0';
blit_dst_offset <= blit_dst_offset + 8;
if blit_dst_cnt_x /= blit_nx then
blit_dst_cnt_x <= blit_dst_cnt_x + 1;
if blit_dst_unaligned = '1' then
@@ -821,6 +847,7 @@ proc_blit_addr_dst:
end if;
elsif blit_dst_do_extra = '1' then
blit_dst_do_extra <= '0';
blit_dst_last <= '1';
else
if blit_dst_cnt_y /= blit_ny then
blit_dst_cnt_x <= (others => '0');