- added BLITTER

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@671 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-11-22 13:50:47 +00:00
parent 3157b3297b
commit 80e3cad985
+218 -17
View File
@@ -123,7 +123,7 @@ architecture Behavioral of vga_frontend64 is
-- Bus master signals
constant MAX_REQUEST_CNT : natural := tsvga.ts_h.ncyc_scan*tsvga.ts_v.ncyc_scan;
signal bufchg : std_logic;
signal bufchg_irq_en : std_logic;
signal bufchg_flag : std_logic;
@@ -158,12 +158,46 @@ architecture Behavioral of vga_frontend64 is
signal read_cnt : unsigned(28 downto 0);
signal bus_read_fin : std_logic;
signal CYC_O_scan : std_logic;
signal STB_O_scan : std_logic;
signal ADDR_O_scan : unsigned(31 downto 0);
signal pixel_cnt : natural range 0 to MAX_REQUEST_CNT/2-1;
signal front : unsigned(31 downto 0);
signal back : unsigned(31 downto 0);
-- Blitter vars
constant BLIT_CHUNK_SIZE : natural := 32;
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);
signal blitfifo_color_in : unsigned(63 downto 0);
signal blit_reset : 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);
signal blit_src_offset : unsigned(31 downto 0);
signal blit_src_finish : std_logic;
signal CYC_O_blit_src : std_logic;
signal STB_O_blit_src : std_logic;
signal ADDR_O_blit_src : unsigned(31 downto 0);
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 CYC_O_blit_dst : std_logic;
signal STB_O_blit_dst : std_logic;
signal ADDR_O_blit_dst : unsigned(31 downto 0);
signal odd_pixel : unsigned(NextExpBaseTwo(tsvga.ts_h.ncyc_scan)-1 downto 0);
-- Bus FIFO
@@ -185,7 +219,7 @@ 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, bus_request, bus_data);
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);
signal s, sn : vm_state_t;
begin
@@ -204,12 +238,34 @@ proc_bufchg_irq:
end if;
end process;
proc_blit_flags:
proc_blit_request_flags:
process(CLK_I)
begin
if rising_edge(CLK_I) then
blit_reset <= '0';
if pixel_cnt_rst = '1' then
blit_request <= '0';
blit_reset <= '1';
elsif blit_request = '0' then
if blit_request_set = '1' then
blit_request <= '1';
blit_reset <= '1';
end if;
elsif blit_dst_finish = '1' and blitfifo_empty = '1' then
blit_request <= '0';
end if;
end if;
end process;
proc_blit_complete_flag:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
blit_request <= '0';
blit_complete <= '0';
elsif blit_dst_finish = '1' and blitfifo_empty = '1' then
blit_complete <= '1';
elsif blit_complete_ack = '1' then
blit_complete <= '0';
end if;
end if;
@@ -301,7 +357,34 @@ 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; -- TODO:
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(32),
data_width => 64,
almost_full_thresh => 24,
almost_empty_thresh => 8
)
PORT MAP
(
rst => RST_I,
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 => blitfifo_almost_full,
fifo_aempty => blitfifo_almost_empty
);
blitfifo_color_in <= MDAT_I;
blitfifo_color_re <= CYC_O_blit_dst and bus_rdy;
blitfifo_color_we <= ACK_I and read_bus_en and CYC_O_blit_src; -- TODO:
-- Instantiate synchronous FIFO
inst_bus_fifo: entity work.fifo_sync
@@ -326,12 +409,16 @@ 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_data_in <= (others => '-');
bus_fifo_addr_in <= ADDR_O_scan;
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 <= '0';
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;
vga_master_next:
process(CLK_I)
begin
@@ -345,11 +432,15 @@ 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)
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)
begin
CYC_O <= '0';
CYC_O_scan <= '0';
STB_O_scan <= '0';
CYC_O_blit_src <= '0';
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';
@@ -371,19 +462,26 @@ vga_master:
when rdy =>
request_cnt_rst <= '1';
if fifo_almost_empty = '1' then
sn <= bus_request;
sn <= scan_bus_request;
elsif blit_request = '1' then
if blitfifo_empty = '1' then
sn <= blit_src_bus_request;
else
sn <= blit_dst_bus_request;
end if;
end if;
when bus_request =>
CYC_O <= '1';
when scan_bus_request =>
CYC_O_scan <= '1';
STB_O_scan <= '1';
request_en <= '1';
read_bus_en <= '1';
if fifo_almost_full = '1' then
sn <= bus_data;
sn <= scan_bus_read;
end if;
when bus_data =>
CYC_O <= '1';
when scan_bus_read =>
CYC_O_scan <= '1';
read_bus_en <= '1';
if bus_read_fin = '1' then
sn <= rdy;
@@ -391,6 +489,37 @@ vga_master:
sn <= idle;
end if;
end if;
when blit_src_bus_request =>
CYC_O_blit_src <= '1';
STB_O_blit_src <= '1';
request_en <= '1';
read_bus_en <= '1';
if blit_chunk_cnt = 0 then
sn <= blit_src_bus_read;
end if;
when blit_src_bus_read =>
CYC_O_blit_src <= '1';
read_bus_en <= '1';
if bus_read_fin = '1' then
sn <= rdy;
end if;
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;
end if;
when blit_dst_bus_fin =>
CYC_O_blit_dst <= '1';
if bus_fifo_empty = '1' then
sn <= rdy;
end if;
when others =>
sn <= idle;
@@ -440,7 +569,7 @@ proc_scan_addr:
if pixel_cnt_rst = '1' then
pixel_cnt <= 0;
front <= host_fb_front;
elsif request_en = '1' and bus_rdy = '1' then
elsif STB_O_scan = '1' and bus_rdy = '1' then
if pixel_cnt /= MAX_REQUEST_CNT/2-1 then
pixel_cnt <= pixel_cnt + 1;
else
@@ -454,6 +583,78 @@ proc_scan_addr:
end if;
end process;
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 blit_reset = '1' then
blit_src_cnt_x <= (others => '0');
blit_src_cnt_y <= (others => '0');
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
if blit_src_cnt_x /= blit_nx then
blit_src_cnt_x <= blit_src_cnt_x + 1;
blit_src_offset <= blit_src_offset + 8;
else
if blit_src_cnt_y /= blit_ny then
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 process;
ADDR_O_blit_dst <= blit_addr_dst + 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
if blit_dst_cnt_x /= blit_nx then
blit_dst_cnt_x <= blit_dst_cnt_x + 1;
blit_dst_offset <= blit_dst_offset + 8;
else
if blit_dst_cnt_y /= blit_ny then
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;
else
blit_dst_finish <= '1';
end if;
end if;
end if;
end if;
end process;
inst_char_gen : entity work.char_gen
GENERIC MAP
(