diff --git a/lib/VGA_ctrl/src/tb_vga_frontend64.vhd b/lib/VGA_ctrl/src/tb_vga_frontend64.vhd index cfaec12..cd8135a 100644 --- a/lib/VGA_ctrl/src/tb_vga_frontend64.vhd +++ b/lib/VGA_ctrl/src/tb_vga_frontend64.vhd @@ -463,12 +463,6 @@ VGA_CLK_GEN: process ack_v(i) := '0'; end loop; else - if blit_count_rst = '1' then - for i in 0 to 127 loop --- ram_dst(i) <= X"DEADBEEF" & X"DEADBEEF"; - ram_dst(i) <= (others => '-'); - end loop; - end if; if (CYC_I and STB_I) = '1' and rdy = '1' then if WE_I = '0' then if ADDR_I(30) = '1' then @@ -490,6 +484,7 @@ VGA_CLK_GEN: process ack_v := ack_v(10 downto 0) & '1'; else -- WE=1 ram_data := ram_dst(to_integer(ADDR_I(31 downto 3))); + ram_data := (others => '-'); if ADDR_I(2) = '0' then if SEL_I = "11111111" then ram_dst(to_integer(ADDR_I(31 downto 3))) <= MDAT_I; @@ -560,9 +555,9 @@ STIMULUS: process STB_O <= '1'; wait until rising_edge(CLK_O) and SRDY_I = '1'; STB_O <= '0'; - CYC_O <= '0'; wait until rising_edge(CLK_O) and ACK_I = '1'; result := SDAT_I; + CYC_O <= '0'; end procedure reg_read; @@ -572,15 +567,17 @@ STIMULUS: process RST_O <= '0'; wait for 60*CLK_PERIOD; + reg_write(X"0000_0018", X"4000_0000"); -- set frontbuffer address + reg_write(X"0000_001C", X"4000_0000"); -- set backbuffer address + reg_write(X"0000_0020", X"0000_0002"); -- set BLIT source address 0 + reg_write(X"0000_0028", X"0000_0002"); -- set BLIT source dimension 0 + reg_write(X"0000_0030", X"0000_0002"); -- set BLIT source address 1 + reg_write(X"0000_0038", X"0000_0002"); -- set BLIT source dimension 1 + reg_write(X"0000_0050", X"0000_0002"); -- set BLIT destination address + reg_write(X"0000_0058", X"0000_0002"); -- set BLIT destination dimension + -- Enable master - CYC_O <= '1'; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '1'; - WE_O <= '1'; - SDAT_O <= X"0000_0002"; - ADDR_O <= X"0000_0000"; - wait until rising_edge(CLK_O) and SRDY_I = '1'; - STB_O <= '0'; + reg_write(X"0000_0000", X"0000_0002"); -- Read status CYC_O <= '1'; @@ -713,7 +710,7 @@ STIMULUS: process for i in 0 to blit_size_array_t'length-1 loop - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT aligned => aligned test @@ -755,7 +752,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", (result and not X"0001_0000") or X"0000_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT unaligned => aligned test ------------------------------------------------- @@ -795,7 +792,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", (result and not X"0001_0000") or X"0000_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT aligned => unaligned test @@ -836,7 +833,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", (result and not X"0001_0000") or X"0000_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT unaligned => unaligned test ------------------------------------------------- @@ -876,7 +873,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", (result and not X"0001_0000") or X"0000_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT const => aligned test ------------------------------------------------- @@ -918,7 +915,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", result or X"0001_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; ------------------------------------------------- -- BLIT const => unaligned test ------------------------------------------------- @@ -960,7 +957,7 @@ STIMULUS: process reg_read(X"0000_0000"); reg_write(X"0000_0000", result or X"0001_0100"); - wait for 600*CLK_PERIOD; +-- wait for 600*CLK_PERIOD; end loop; state <= IDLE; diff --git a/lib/VGA_ctrl/src/vga_frontend64.vhd b/lib/VGA_ctrl/src/vga_frontend64.vhd index d91f09f..b812135 100644 --- a/lib/VGA_ctrl/src/vga_frontend64.vhd +++ b/lib/VGA_ctrl/src/vga_frontend64.vhd @@ -31,6 +31,7 @@ entity vga_frontend64 is fifo_almost_full_thresh : natural := 4000; fifo_almost_empty_thresh : natural := 800; BLIT_CHUNK_SIZE : natural := 512; + BLIT_CMD_FIFO_DEPTH : natural := 16; tsvga : vga_timespec_t := ts_vga_800_600_72 ); Port @@ -80,95 +81,123 @@ end vga_frontend64; architecture Behavioral of vga_frontend64 is -- Color FIFO signals - signal fifo_full : std_logic; - signal fifo_empty : std_logic; - signal fifo_almost_empty : std_logic; - signal fifo_almost_full : std_logic; - signal fifo_color_re : std_logic; - signal fifo_color_we : std_logic; - signal fifo_color_out : unsigned(63 downto 0); - signal fifo_color_in : unsigned(63 downto 0); + signal fifo_full : std_logic; + signal fifo_empty : std_logic; + signal fifo_almost_empty : std_logic; + signal fifo_almost_full : std_logic; + signal fifo_color_re : std_logic; + signal fifo_color_we : std_logic; + signal fifo_color_out : unsigned(63 downto 0); + signal fifo_color_in : unsigned(63 downto 0); -- Backend signals - signal scan_rdy : std_logic; - signal ctrl_scan_en : std_logic; - signal color_in : color_array_t; - signal color_op : color_op_t; - signal color_en : unsigned (VGA_NUM_CH-1 downto 0); + signal scan_rdy : std_logic; + signal ctrl_scan_en : std_logic; + signal color_in : color_array_t; + signal color_op : color_op_t; + signal color_en : unsigned (VGA_NUM_CH-1 downto 0); - signal stat_vga_rdy : std_logic; - signal stat_hready : std_logic; - signal stat_vready : std_logic; - signal stat_scan : std_logic; - signal stat_hscan : std_logic; - signal stat_vscan : std_logic; - signal stat_hsync : std_logic; - signal stat_vsync : std_logic; - signal stat_hpos : natural range 0 to tsvga.ts_h.ncyc_scan-1; - signal stat_vpos : natural range 0 to tsvga.ts_v.ncyc_scan-1; + signal stat_vga_rdy : std_logic; + signal stat_hready : std_logic; + signal stat_vready : std_logic; + signal stat_scan : std_logic; + signal stat_hscan : std_logic; + signal stat_vscan : std_logic; + signal stat_hsync : std_logic; + signal stat_vsync : std_logic; + signal stat_hpos : natural range 0 to tsvga.ts_h.ncyc_scan-1; + signal stat_vpos : natural range 0 to tsvga.ts_v.ncyc_scan-1; -- CG signals - signal cg_en : std_logic; - signal cg_rdy : std_logic; - signal cg_draw : std_logic; - signal cg_clr_screen : std_logic; - signal cg_clr_line : std_logic; - signal cg_din : unsigned(7 downto 0); - signal cg_dout : unsigned(7 downto 0); - signal cg_ascii_we : std_logic; - signal cg_posy_we : std_logic; - signal cg_posx_we : std_logic; - signal cg_color : color_t; - signal cg_csr_pos_x : natural range 0 to 80-1; - signal cg_csr_pos_y : natural range 0 to 32-1; + signal cg_en : std_logic; + signal cg_rdy : std_logic; + signal cg_draw : std_logic; + signal cg_clr_screen : std_logic; + signal cg_clr_line : std_logic; + signal cg_din : unsigned(7 downto 0); + signal cg_dout : unsigned(7 downto 0); + signal cg_ascii_we : std_logic; + signal cg_posy_we : std_logic; + signal cg_posx_we : std_logic; + signal cg_color : color_t; + signal cg_csr_pos_x : natural range 0 to 80-1; + signal cg_csr_pos_y : natural range 0 to 32-1; -- 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; - signal bufchg_flag_ack : std_logic; - signal vga_fb_back : unsigned(31 downto 0); - signal vga_fb_front : unsigned(31 downto 0); - signal host_fb_front : unsigned(31 downto 0); - signal host_fb_back : unsigned(31 downto 0); - signal blit_addr_src_0 : unsigned(31 downto 0); - signal blit_addr_src_1 : unsigned(31 downto 0); - signal blit_addr_dst : unsigned(31 downto 0); - signal blit_dimx_src_0 : unsigned(31 downto 0); - signal blit_dimx_src_1 : unsigned(31 downto 0); - signal blit_dimx_dst : unsigned(31 downto 0); - signal blit_nx : unsigned(31 downto 0); - signal blit_ny : unsigned(31 downto 0); - signal blit_func_sel : unsigned(3 downto 0); - signal blit_comb_sel : unsigned(3 downto 0); - signal blit_request : std_logic; - signal blit_request_set : std_logic; - 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_scan_dma_en : std_logic; - signal vga_scan_dma_en2 : std_logic; - signal request_cnt_rst : std_logic; - signal request_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; - 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); + 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; + signal bufchg_flag_ack : std_logic; + signal vga_fb_back : unsigned(31 downto 0); + signal vga_fb_front : unsigned(31 downto 0); + signal host_fb_front : unsigned(31 downto 0); + signal host_fb_back : unsigned(31 downto 0); + signal blit_reg_addr_src_0 : unsigned(31 downto 0); + signal blit_reg_addr_src_1 : unsigned(31 downto 0); + signal blit_reg_addr_dst : unsigned(31 downto 0); + signal blit_reg_dimx_src_0 : unsigned(31 downto 0); + signal blit_reg_dimx_src_1 : unsigned(31 downto 0); + signal blit_reg_dimx_dst : unsigned(31 downto 0); + signal blit_reg_nx : unsigned(31 downto 0); + signal blit_reg_ny : unsigned(31 downto 0); + signal blit_reg_const_color : unsigned(31 downto 0); + signal blit_reg_func : unsigned(7 downto 0); + signal vga_scan_rdy : 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 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; + 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 + signal blit_reset : std_logic; + signal blit_request : std_logic; + signal blit_const_color_en : std_logic; + signal blit_request_set : std_logic; + signal blit_finish_strobe : unsigned(2 downto 0); + signal blit_complete_int : std_logic; + signal blit_complete_int_ack : std_logic; + signal blit_complete_int_en : std_logic; + signal blit_cmd_empty_int : std_logic; + signal blit_cmd_empty_int_ack : std_logic; + signal blit_cmd_empty_int_en : std_logic; + + -- BLIT command FIFO + constant BLIT_CMD_FIFO_WIDTH : natural := 320; + signal blit_cmd_din : unsigned(BLIT_CMD_FIFO_WIDTH-1 downto 0); + signal blit_cmd_dout : unsigned(BLIT_CMD_FIFO_WIDTH-1 downto 0); + signal blit_cmd_re : std_logic; + signal blit_cmd_we : std_logic; + signal blit_cmd_empty : std_logic; + signal blit_cmd_full : std_logic; + signal blit_cmd_bsy : std_logic; + signal blit_cmd_avail : std_logic; + + signal blit_cmd_addr_src_0 : unsigned(31 downto 0); + signal blit_cmd_addr_src_1 : unsigned(31 downto 0); + signal blit_cmd_addr_dst : unsigned(31 downto 0); + signal blit_cmd_dimx_src_0 : unsigned(31 downto 0); + signal blit_cmd_dimx_src_1 : unsigned(31 downto 0); + signal blit_cmd_dimx_dst : unsigned(31 downto 0); + signal blit_cmd_nx : unsigned(31 downto 0); + signal blit_cmd_ny : unsigned(31 downto 0); + signal blit_cmd_CC : unsigned(31 downto 0); + signal blit_cmd_func : unsigned(31 downto 0); + signal blit_chunk_cnt : natural range 0 to BLIT_CHUNK_SIZE-1; signal blit_chunk_full : std_logic; @@ -220,9 +249,6 @@ architecture Behavioral of vga_frontend64 is signal blit_fill_finish : std_logic; signal blit_fill_addr : unsigned(2 downto 0); - signal blit_const_color : unsigned(31 downto 0); - signal blit_const_color_en : 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); @@ -268,8 +294,6 @@ architecture Behavioral of vga_frontend64 is LAST : std_logic; UNALIGNED : std_logic; PARTIAL : std_logic; - N_ODD : std_logic; - re : unsigned(1 downto 0); end record debug_t; signal src_dbg : debug_t; @@ -279,6 +303,55 @@ architecture Behavioral of vga_frontend64 is -------------------------------------------------------------------------- begin + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-1 downto BLIT_CMD_FIFO_WIDTH-32) <= blit_reg_addr_src_0; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-32-1 downto BLIT_CMD_FIFO_WIDTH-64) <= blit_reg_dimx_src_0; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-64-1 downto BLIT_CMD_FIFO_WIDTH-96) <= blit_reg_addr_src_1; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-96-1 downto BLIT_CMD_FIFO_WIDTH-128) <= blit_reg_dimx_src_1; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-128-1 downto BLIT_CMD_FIFO_WIDTH-160) <= blit_reg_addr_dst; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-160-1 downto BLIT_CMD_FIFO_WIDTH-192) <= blit_reg_dimx_dst; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-192-1 downto BLIT_CMD_FIFO_WIDTH-224) <= blit_reg_nx; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-224-1 downto BLIT_CMD_FIFO_WIDTH-256) <= blit_reg_ny; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-256-1 downto BLIT_CMD_FIFO_WIDTH-288) <= blit_reg_const_color; + blit_cmd_din(BLIT_CMD_FIFO_WIDTH-288-1 downto BLIT_CMD_FIFO_WIDTH-320) <= (31 downto 8 => '0') & blit_reg_func; + + blit_cmd_addr_src_0 <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-1 downto BLIT_CMD_FIFO_WIDTH-32); + blit_cmd_dimx_src_0 <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-32-1 downto BLIT_CMD_FIFO_WIDTH-64); + blit_cmd_addr_src_1 <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-64-1 downto BLIT_CMD_FIFO_WIDTH-96); + blit_cmd_dimx_src_1 <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-96-1 downto BLIT_CMD_FIFO_WIDTH-128); + blit_cmd_addr_dst <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-128-1 downto BLIT_CMD_FIFO_WIDTH-160); + blit_cmd_dimx_dst <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-160-1 downto BLIT_CMD_FIFO_WIDTH-192); + blit_cmd_nx <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-192-1 downto BLIT_CMD_FIFO_WIDTH-224); + blit_cmd_ny <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-224-1 downto BLIT_CMD_FIFO_WIDTH-256); + blit_cmd_CC <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-256-1 downto BLIT_CMD_FIFO_WIDTH-288); + blit_cmd_func <= blit_cmd_dout(BLIT_CMD_FIFO_WIDTH-288-1 downto BLIT_CMD_FIFO_WIDTH-320); + + blit_cmd_avail <= not blit_cmd_empty; + blit_cmd_bsy <= blit_cmd_full; + blit_cmd_re <= blit_finish_strobe(0); + blit_cmd_we <= blit_request_set; + +-- Command FIFO +inst_blit_cmd_fifo: entity work.fifo_sync + GENERIC MAP + ( + addr_width => NextExpBaseTwo(BLIT_CMD_FIFO_DEPTH), + data_width => BLIT_CMD_FIFO_WIDTH, + do_last_read_update => false + ) + PORT MAP + ( + rst => RST_I, + clk => CLK_I, + we => blit_cmd_we, + re => blit_cmd_re, + fifo_full => blit_cmd_full, + fifo_empty => blit_cmd_empty, + fifo_afull => open, + fifo_aempty => open, + data_w => blit_cmd_din, + data_r => blit_cmd_dout + ); + proc_synced_vga_scan_en: process(CLK_I) begin @@ -291,46 +364,31 @@ proc_synced_vga_scan_en: end if; end process; -proc_bufchg_irq: + ADDR_O_scan <= front + (to_unsigned(pixel_cnt, 29) & "000"); + +proc_scan_addr: process(CLK_I) begin if rising_edge(CLK_I) then - if vga_scan_dma_en2 = '0' or bufchg_flag_ack = '1' then - bufchg_flag <= '0'; - elsif bufchg = '1' then - bufchg_flag <= '1'; - end if; - INT_O <= (bufchg_flag and bufchg_irq_en) - or (blit_complete and blit_complete_inten); + bufchg <= '0'; + if vga_scan_dma_en2 = '0' then + pixel_cnt <= 0; + front <= host_fb_front; + elsif STB_O_scan = '1' and busout_fifo_rdy = '1' then + if pixel_cnt /= MAX_REQUEST_CNT/2-1 then + pixel_cnt <= pixel_cnt + 1; + else + pixel_cnt <= 0; + front <= host_fb_back; + bufchg <= '1'; + end if; + end if; + vga_fb_front <= front; + vga_fb_back <= back; end if; end process; - -proc_blit_request_flags: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if RST_I = '1' then - blit_request <= '0'; - elsif blit_request_set = '1' then - blit_request <= '1'; - elsif blit_dst_finish = '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' or blit_request_set = '1' or blit_complete_ack = '1' then - blit_complete <= '0'; - elsif blit_dst_finish = '1' and blit_request = '1' then - blit_complete <= '1'; - end if; - end if; - end process; - + +--------------------------------------------------------------------------------- inst_vga_backend : entity work.vga_backend GENERIC MAP ( @@ -391,6 +449,7 @@ inst_vga_backend : entity work.vga_backend color_op <= op_over; vga_scan_rdy <= stat_hready and stat_vready; +-- SCAN line FIFO inst_linefifo: entity work.fifo_async GENERIC MAP ( @@ -468,10 +527,13 @@ inst_busout_fifo: entity work.fifo_sync data_w => busout_fifo_din, data_r => busout_fifo_dout ); + + blit_const_color_en <= blit_cmd_func(0); + busout_fifo_rdy <= not busout_fifo_full; busout_fifo_re <= not busout_fifo_empty and SRDY_I; busout_fifo_we <= bus_cycle_en and (STB_O_scan or STB_O_blit_src or STB_O_blit_dst); - busout_fifo_data_in <= (blitfifo_dout_1 & blitfifo_dout_0) when blit_const_color_en = '0' else (blit_const_color & blit_const_color); + busout_fifo_data_in <= (blitfifo_dout_1 & blitfifo_dout_0) when blit_const_color_en = '0' else (blit_cmd_CC & blit_cmd_CC); busout_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; @@ -480,33 +542,47 @@ inst_busout_fifo: entity work.fifo_sync request_en <= bus_cycle_en and busout_fifo_we and busout_fifo_rdy; CYC_O <= bus_cycle_en; ---------------------------------------------------------------------------------- - ADDR_O_scan <= front + (to_unsigned(pixel_cnt, 29) & "000"); - -proc_scan_addr: +------------------------------------------------------------------------------------ +-- Bus request counter +------------------------------------------------------------------------------------ +proc_bus_request_counter: process(CLK_I) begin if rising_edge(CLK_I) then - bufchg <= '0'; - if vga_scan_dma_en2 = '0' then - pixel_cnt <= 0; - front <= host_fb_front; - elsif STB_O_scan = '1' and busout_fifo_rdy = '1' then - if pixel_cnt /= MAX_REQUEST_CNT/2-1 then - pixel_cnt <= pixel_cnt + 1; - else - pixel_cnt <= 0; - front <= host_fb_back; - bufchg <= '1'; - end if; - end if; - vga_fb_front <= front; - vga_fb_back <= back; + if request_cnt_rst = '1' then + request_cnt <= (others => '0'); + elsif request_en = '1' then + request_cnt <= request_cnt + 1; + end if; end if; end process; - + +proc_bus_read_counter: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if request_cnt_rst = '1' then + read_cnt <= (others => '0'); + elsif busin_fifo_dout_vld = '1' then + read_cnt <= read_cnt + 1; + end if; + end if; + end process; + +proc_bus_read_finish: + process(CLK_I) + begin + if rising_edge(CLK_I) then + bus_read_fin <= '0'; + if read_cnt = request_cnt then + bus_read_fin <= '1'; + end if; + end if; + end process; + ------------------------------------------------------------------------------------ -- VGA master FSM +------------------------------------------------------------------------------------ vga_master_next: process(CLK_I) begin @@ -619,38 +695,58 @@ vga_master: end case; end process; ------------------------------------------------------------------------------------- -proc_bus_request_counter: +--------------------------------------------------------------------------------- +-- BLITTER +--------------------------------------------------------------------------------- +proc_blit_complete_int_flag: process(CLK_I) begin if rising_edge(CLK_I) then - if request_cnt_rst = '1' then - request_cnt <= (others => '0'); - elsif request_en = '1' then - request_cnt <= request_cnt + 1; - end if; - end if; - end process; - -proc_bus_read_counter: - process(CLK_I) - begin - if rising_edge(CLK_I) then - if request_cnt_rst = '1' then - read_cnt <= (others => '0'); - elsif busin_fifo_dout_vld = '1' then - read_cnt <= read_cnt + 1; - end if; + if RST_I = '1' or (blit_complete_int = '1' and blit_complete_int_ack = '1') then + blit_complete_int <= '0'; + elsif blit_finish_strobe(2) = '1' or (blit_complete_int = '0' and blit_complete_int_ack = '1') then + blit_complete_int <= '1'; + end if; end if; end process; -proc_bus_read_finish: +proc_blit_cmd_empty_int_flag: process(CLK_I) begin if rising_edge(CLK_I) then - bus_read_fin <= '0'; - if read_cnt = request_cnt then - bus_read_fin <= '1'; + if RST_I = '1' or (blit_cmd_empty_int = '1' and blit_cmd_empty_int_ack = '1') then + blit_cmd_empty_int <= '0'; + elsif (blit_finish_strobe(2) = '1' and blit_cmd_avail = '0') or (blit_cmd_empty_int = '0' and blit_cmd_empty_int_ack = '1') then + blit_cmd_empty_int <= '1'; + end if; + end if; + end process; + +proc_irq: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if vga_scan_dma_en2 = '0' or bufchg_flag_ack = '1' then + bufchg_flag <= '0'; + elsif bufchg = '1' then + bufchg_flag <= '1'; + end if; + INT_O <= (bufchg_flag and bufchg_irq_en) + or (blit_complete_int and blit_complete_int_en) + or (blit_cmd_empty_int and blit_cmd_empty_int_en); + end if; + end process; + +proc_blit_reset: + process(CLK_I) + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + blit_reset <= '1'; + blit_request <= '0'; + else + blit_reset <= (blit_cmd_avail and not blit_request) or (blit_request and blit_finish_strobe(0)); + blit_request <= blit_cmd_avail; end if; end if; end process; @@ -672,6 +768,7 @@ proc_blit_chunk_counter: end if; end process; +-- BLIT buffer low inst_blitfifo_src0: entity work.fifo_sync GENERIC MAP ( @@ -696,6 +793,7 @@ inst_blitfifo_src0: entity work.fifo_sync ); +-- BLIT buffer high inst_blitfifo_src1: entity work.fifo_sync GENERIC MAP ( @@ -726,10 +824,6 @@ inst_blitfifo_src1: entity work.fifo_sync blitfifo_dout_vld <= not (blitfifo_empty(0) and blitfifo_empty(1)); --------------------------------------------------------------------------------- - blit_reset <= RST_I or (blit_request_set and not blit_request); - ---------------------------------------------------------------------------------- - blit_dst_be_gen: process(dst_dbg) begin @@ -790,14 +884,13 @@ blitfifo_re_gen: empty_read := (blitfifo_empty(0) and fifo_re(0)) or (blitfifo_empty(1) and fifo_re(1)); blitfifo_re <= fifo_re and not (empty_read & empty_read); blitfifo_empty_read <= empty_read; - dst_dbg.re <= fifo_re; end process; blit_dst_suspend_gen: process(CLK_I) begin if rising_edge(CLK_I) then - if blit_reset = '1' or CYC_O_blit_src = '1' then + if RST_I = '1' or blit_dst_finish = '1' or CYC_O_blit_src = '1' then blit_dst_suspend <= '0'; elsif blitfifo_read_en = '1' and blitfifo_empty_read = '1' then blit_dst_suspend <= not (blitfifo_empty(0) and blitfifo_empty(1)); @@ -806,43 +899,41 @@ blit_dst_suspend_gen: end process; fill_dbg.LAST <= '1' when blit_fill_cnt_x_next = '0' & X"0000_0000" or blit_fill_cnt_x_next(32) = '1' else '0'; - fill_dbg.PARTIAL <= blit_fill_cnt_x_next(32); - fill_dbg.N_ODD <= blit_nx(1); + fill_dbg.PARTIAL <= blit_fill_cnt_x_next(32); blit_fill_cnt_x_next <= ('0' & blit_fill_cnt_x - 1) when fill_dbg.FIRST = '1' and fill_dbg.UNALIGNED = '1' else ('0' & blit_fill_cnt_x - 2); +-- BLIT Buffer fill address generator blitfifo_fill_src_0: process(CLK_I) variable addr_next : unsigned(31 downto 0); begin if rising_edge(CLK_I) then - if blit_reset = '1' then - blit_fill_addr <= blit_addr_src_0(2) & "00"; - blit_fill_cnt_x <= blit_nx; - blit_fill_cnt_y <= blit_ny; - blit_fill_offset <= blit_dimx_src_0(2 downto 0); - blit_fill_finish <= blit_const_color_en; - fill_dbg.FIRST <= not blit_const_color_en; - fill_dbg.UNALIGNED <= blit_addr_src_0(2); - elsif blit_request = '1' then - if blit_fill_finish = '0' and blitfifo_write_en = '1' then - fill_dbg.FIRST <= '0'; - if fill_dbg.LAST = '1' then - if blit_fill_cnt_y < X"0000_0002" then - blit_fill_finish <= '1'; - else - addr_next := (blit_addr_src_0(31 downto 2) & "00") + blit_fill_offset; - blit_fill_addr <= addr_next(2 downto 0); - blit_fill_offset <= blit_fill_offset + blit_dimx_src_0(2 downto 0); - blit_fill_cnt_x <= blit_nx; - blit_fill_cnt_y <= blit_fill_cnt_y - 1; - fill_dbg.FIRST <= '1'; - fill_dbg.UNALIGNED <= addr_next(2); - end if; + if RST_I = '1' or blit_reset = '1' then + blit_fill_addr <= blit_cmd_addr_src_0(2) & "00"; + blit_fill_cnt_x <= blit_cmd_nx; + blit_fill_cnt_y <= blit_cmd_ny; + blit_fill_offset <= blit_cmd_dimx_src_0(2 downto 0); + blit_fill_finish <= '0'; + fill_dbg.FIRST <= '1'; + fill_dbg.UNALIGNED <= blit_cmd_addr_src_0(2); + elsif blit_request = '1' and blit_fill_finish = '0' and blit_const_color_en = '0' and blitfifo_write_en = '1' then + fill_dbg.FIRST <= '0'; + if fill_dbg.LAST = '1' then + if blit_fill_cnt_y < X"0000_0002" then + blit_fill_finish <= '1'; else - blit_fill_cnt_x <= blit_fill_cnt_x_next(31 downto 0); - blit_fill_addr <= (others => '0'); + addr_next := (blit_cmd_addr_src_0(31 downto 2) & "00") + blit_fill_offset; + blit_fill_addr <= addr_next(2 downto 0); + blit_fill_offset <= blit_fill_offset + blit_cmd_dimx_src_0(2 downto 0); + blit_fill_cnt_x <= blit_cmd_nx; + blit_fill_cnt_y <= blit_fill_cnt_y - 1; + fill_dbg.FIRST <= '1'; + fill_dbg.UNALIGNED <= addr_next(2); end if; + else + blit_fill_cnt_x <= blit_fill_cnt_x_next(31 downto 0); + blit_fill_addr <= (others => '0'); end if; end if; end if; @@ -850,43 +941,41 @@ blitfifo_fill_src_0: src_dbg.LAST <= '1' when blit_src_cnt_x_next = '0' & X"0000_0000" or blit_src_cnt_x_next(32) = '1' else '0'; src_dbg.PARTIAL <= blit_src_cnt_x_next(32); - src_dbg.N_ODD <= blit_nx(1); blit_src_addr_next <= ADDR_O_blit_src + 8; blit_src_cnt_x_next <= ('0' & blit_src_cnt_x - 1) when src_dbg.FIRST = '1' and src_dbg.UNALIGNED = '1' else ('0' & blit_src_cnt_x - 2); +-- BLIT Source address generator blit_request_addr_src: process(CLK_I) variable addr_next : unsigned(31 downto 0); begin if rising_edge(CLK_I) then - if blit_reset = '1' then - ADDR_O_blit_src <= blit_addr_src_0(31 downto 2) & "00"; - blit_src_cnt_x <= blit_nx; - blit_src_cnt_y <= blit_ny; - blit_src_offset <= blit_dimx_src_0; - blit_src_finish <= blit_const_color_en; - src_dbg.FIRST <= not blit_const_color_en; - src_dbg.UNALIGNED <= blit_addr_src_0(2); - elsif blit_request = '1' then - if blit_src_finish = '0' and (STB_O_blit_src = '1' and busout_fifo_rdy = '1') then - src_dbg.FIRST <= '0'; - if src_dbg.LAST = '1' then - if blit_src_cnt_y < X"0000_0002" then - blit_src_finish <= '1'; - else - addr_next := (blit_addr_src_0(31 downto 2) & "00") + blit_src_offset; - ADDR_O_blit_src <= addr_next; - blit_src_offset <= blit_src_offset + blit_dimx_src_0; - blit_src_cnt_x <= blit_nx; - blit_src_cnt_y <= blit_src_cnt_y - 1; - src_dbg.FIRST <= '1'; - src_dbg.UNALIGNED <= addr_next(2); - end if; + if RST_I = '1' or blit_reset = '1' then + ADDR_O_blit_src <= blit_cmd_addr_src_0(31 downto 2) & "00"; + blit_src_cnt_x <= blit_cmd_nx; + blit_src_cnt_y <= blit_cmd_ny; + blit_src_offset <= blit_cmd_dimx_src_0; + blit_src_finish <= '0'; + src_dbg.FIRST <= '1'; + src_dbg.UNALIGNED <= blit_cmd_addr_src_0(2); + elsif blit_request = '1' and blit_src_finish = '0' and blit_const_color_en = '0' and (STB_O_blit_src = '1' and busout_fifo_rdy = '1') then + src_dbg.FIRST <= '0'; + if src_dbg.LAST = '1' then + if blit_src_cnt_y < X"0000_0002" then + blit_src_finish <= '1'; else - ADDR_O_blit_src <= blit_src_addr_next; - blit_src_cnt_x <= blit_src_cnt_x_next(31 downto 0); + addr_next := (blit_cmd_addr_src_0(31 downto 2) & "00") + blit_src_offset; + ADDR_O_blit_src <= addr_next; + blit_src_offset <= blit_src_offset + blit_cmd_dimx_src_0; + blit_src_cnt_x <= blit_cmd_nx; + blit_src_cnt_y <= blit_src_cnt_y - 1; + src_dbg.FIRST <= '1'; + src_dbg.UNALIGNED <= addr_next(2); end if; + else + ADDR_O_blit_src <= blit_src_addr_next; + blit_src_cnt_x <= blit_src_cnt_x_next(31 downto 0); end if; end if; end if; @@ -895,49 +984,52 @@ blit_request_addr_src: dst_dbg.LAST <= '1' when blit_dst_cnt_x_next = '0' & X"0000_0000" or blit_dst_cnt_x_next(32) = '1' else '0'; dst_dbg.PARTIAL <= blit_dst_cnt_x_next(32); - dst_dbg.N_ODD <= blit_nx(1); blit_dst_addr_next <= ADDR_O_blit_dst + 8; blit_dst_cnt_x_next <= ('0' & blit_dst_cnt_x - 1) when dst_dbg.FIRST = '1' and dst_dbg.UNALIGNED = '1' else ('0' & blit_dst_cnt_x - 2); +-- BLIT Destination address generator blit_request_addr_dst: process(CLK_I) variable addr_next : unsigned(31 downto 0); begin if rising_edge(CLK_I) then - if blit_reset = '1' then - ADDR_O_blit_dst <= blit_addr_dst(31 downto 2) & "00"; - blit_dst_cnt_x <= blit_nx; - blit_dst_cnt_y <= blit_ny; - blit_dst_offset <= blit_dimx_dst; + blit_finish_strobe <= blit_finish_strobe(blit_finish_strobe'left-1 downto 0) & '0'; + if RST_I = '1' then + blit_finish_strobe <= (others =>'0'); + elsif blit_reset = '1' then + ADDR_O_blit_dst <= blit_cmd_addr_dst(31 downto 2) & "00"; + blit_dst_cnt_x <= blit_cmd_nx; + blit_dst_cnt_y <= blit_cmd_ny; + blit_dst_offset <= blit_cmd_dimx_dst; blit_dst_finish <= '0'; dst_dbg.FIRST <= '1'; - dst_dbg.UNALIGNED <= blit_addr_dst(2); - elsif blit_request = '1' then - if blit_dst_finish = '0' and (STB_O_blit_dst = '1' and busout_fifo_rdy = '1') then - dst_dbg.FIRST <= '0'; - if dst_dbg.LAST = '1' then - if blit_dst_cnt_y < X"0000_0002" then - blit_dst_finish <= '1'; - else - addr_next := (blit_addr_dst(31 downto 2) & "00") + blit_dst_offset; - ADDR_O_blit_dst <= addr_next; - blit_dst_offset <= blit_dst_offset + blit_dimx_dst; - blit_dst_cnt_x <= blit_nx; - blit_dst_cnt_y <= blit_dst_cnt_y - 1; - dst_dbg.FIRST <= '1'; - dst_dbg.UNALIGNED <= addr_next(2); - end if; + dst_dbg.UNALIGNED <= blit_cmd_addr_dst(2); + elsif blit_request = '1' and blit_dst_finish = '0' and (STB_O_blit_dst = '1' and busout_fifo_rdy = '1') then + dst_dbg.FIRST <= '0'; + if dst_dbg.LAST = '1' then + if blit_dst_cnt_y < X"0000_0002" then + blit_dst_finish <= '1'; + blit_finish_strobe(0) <= '1'; else - ADDR_O_blit_dst <= blit_dst_addr_next; - blit_dst_cnt_x <= blit_dst_cnt_x_next(31 downto 0); + addr_next := (blit_cmd_addr_dst(31 downto 2) & "00") + blit_dst_offset; + ADDR_O_blit_dst <= addr_next; + blit_dst_offset <= blit_dst_offset + blit_cmd_dimx_dst; + blit_dst_cnt_x <= blit_cmd_nx; + blit_dst_cnt_y <= blit_dst_cnt_y - 1; + dst_dbg.FIRST <= '1'; + dst_dbg.UNALIGNED <= addr_next(2); end if; + else + ADDR_O_blit_dst <= blit_dst_addr_next; + blit_dst_cnt_x <= blit_dst_cnt_x_next(31 downto 0); end if; end if; end if; end process; - +--------------------------------------------------------------------------------- +-- Character generator --------------------------------------------------------------------------------- inst_char_gen : entity work.char_gen GENERIC MAP @@ -977,8 +1069,10 @@ inst_char_gen : entity work.char_gen ); scan_rdy <= stat_hready and stat_vready; cg_en <= stat_scan; - +--------------------------------------------------------------------------------- +-- JBUS registers +--------------------------------------------------------------------------------- registers_read: process(CLK_I) begin @@ -996,11 +1090,13 @@ registers_read: SDAT_O(1) <= vga_scan_dma_en; SDAT_O(2) <= bufchg_irq_en; SDAT_O(3) <= bufchg_flag; - SDAT_O(8) <= blit_request; - SDAT_O(9) <= blit_complete; - SDAT_O(10) <= blit_complete_inten; - SDAT_O(23 downto 20) <= blit_comb_sel; - SDAT_O(19 downto 16) <= blit_func_sel; + SDAT_O(8) <= blit_cmd_bsy; + SDAT_O(9) <= blit_complete_int; + SDAT_O(10) <= blit_complete_int_en; + SDAT_O(11) <= blit_cmd_empty_int; + SDAT_O(12) <= blit_cmd_empty_int_en; + SDAT_O(23 downto 16) <= blit_reg_func(7 downto 0); + SDAT_O(31) <= blit_request; -- RO: Blitter is active. Blit jobs avaliable in CMD-FIFO -- sys_vga_ascii -- 0x04 @@ -1040,39 +1136,42 @@ registers_read: -- sys_blit_descr_src_0 -- 0x20 when "01000" => - SDAT_O <= blit_addr_src_0; + SDAT_O <= blit_reg_addr_src_0; -- 0x28 when "01010" => - SDAT_O <= blit_dimx_src_0; + SDAT_O <= blit_reg_dimx_src_0; -- sys_blit_descr_src_1 -- 0x30 when "01100" => - SDAT_O <= blit_addr_src_1; + SDAT_O <= blit_reg_addr_src_1; -- 0x38 when "01110" => - SDAT_O <= blit_dimx_src_1; + SDAT_O <= blit_reg_dimx_src_1; -- sys_blit_descr_dst -- 0x50 when "10100" => - SDAT_O <= blit_addr_dst; + SDAT_O <= blit_reg_addr_dst; + when "10101" => + SDAT_O <= blit_reg_const_color; + -- 0x58 when "10110" => - SDAT_O <= blit_dimx_dst; + SDAT_O <= blit_reg_dimx_dst; - -- sys_blit_nx + -- sys_blit_reg_nx -- 0x60 when "11000" => - SDAT_O <= blit_nx; + SDAT_O <= blit_reg_nx; - -- sys_blit_ny + -- sys_blit_reg_ny -- 0x64 when "11001" => - SDAT_O <= blit_ny; + SDAT_O <= blit_reg_ny; when others => null; end case; @@ -1080,125 +1179,131 @@ registers_read: end if; end process; - blit_const_color_en <= blit_func_sel(0); registers_write: process(CLK_I) begin if rising_edge(CLK_I) then - cg_ascii_we <= '0'; - cg_posy_we <= '0'; - cg_posx_we <= '0'; - cg_clr_screen <= '0'; - cg_clr_line <= '0'; - bufchg_flag_ack <= '0'; - blit_request_set <= '0'; - blit_complete_ack <= '0'; + cg_ascii_we <= '0'; + cg_posy_we <= '0'; + cg_posx_we <= '0'; + cg_clr_screen <= '0'; + cg_clr_line <= '0'; + bufchg_flag_ack <= '0'; + blit_request_set <= '0'; + blit_complete_int_ack <= '0'; + blit_cmd_empty_int_ack <= '0'; if RST_I = '1' then - cg_din <= (others => '0'); - vga_scan_dma_en <= '0'; - bufchg_irq_en <= '0'; - blit_complete_inten <= '0'; - blit_func_sel <= (others => '0'); - 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"); + cg_din <= (others => '0'); + vga_scan_dma_en <= '0'; + bufchg_irq_en <= '0'; + blit_complete_int_en <= '0'; + blit_cmd_empty_int_en <= '0'; + blit_reg_func <= (others => '0'); + blit_reg_addr_src_0 <= (others => '0'); + blit_reg_addr_src_1 <= (others => '0'); + blit_reg_dimx_src_0 <= (others => '0'); + blit_reg_dimx_src_1 <= (others => '0'); + blit_reg_addr_dst <= (others => '0'); + blit_reg_dimx_dst <= (others => '0'); + blit_reg_nx <= (others => '0'); + blit_reg_ny <= (others => '0'); + host_fb_front <= (others => '0'); + host_fb_back <= (others => '0'); + 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 -- sys_vga_ctrl -- 0x00 when "00000" => - 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); - cg_clr_line <= SDAT_I(5); - blit_request_set <= SDAT_I(8); - blit_complete_ack <= SDAT_I(9); - blit_complete_inten <= SDAT_I(10); - blit_func_sel <= SDAT_I(19 downto 16); - blit_comb_sel <= SDAT_I(23 downto 20); + 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); + cg_clr_line <= SDAT_I(5); + blit_request_set <= SDAT_I(8); + blit_complete_int_ack <= SDAT_I(9); + blit_complete_int_en <= SDAT_I(10); + blit_cmd_empty_int_ack <= SDAT_I(11); + blit_cmd_empty_int_en <= SDAT_I(12); + blit_reg_func <= SDAT_I(23 downto 16); -- sys_vga_ascii -- 0x04 when "00001" => cg_ascii_we <= '1'; - cg_din <= SDAT_I(7 downto 0); + cg_din <= SDAT_I(7 downto 0); -- sys_vga_posx -- 0x08 when "00010" => - cg_posx_we <= '1'; - cg_din <= SDAT_I(7 downto 0); + cg_posx_we <= '1'; + cg_din <= SDAT_I(7 downto 0); -- sys_vga_posy -- 0x0C when "00011" => - cg_posy_we <= '1'; - cg_din <= SDAT_I(7 downto 0); + cg_posy_we <= '1'; + cg_din <= SDAT_I(7 downto 0); -- sys_vga_cgcol -- 0x10 when "00100" => - cg_color <= to_color_t(SDAT_I(31 downto 0)); + cg_color <= to_color_t(SDAT_I(31 downto 0)); -- sys_vga_fb_front -- 0x18 when "00110" => - host_fb_front <= SDAT_I(31 downto 3) & "000"; + host_fb_front <= SDAT_I(31 downto 3) & "000"; -- sys_vga_fb_back -- 0x1C when "00111" => bufchg_flag_ack <= '1'; - host_fb_back <= SDAT_I(31 downto 3) & "000"; + host_fb_back <= SDAT_I(31 downto 3) & "000"; -- sys_blit_descr_src_0 -- 0x20 when "01000" => - blit_addr_src_0 <= SDAT_I(31 downto 0); + blit_reg_addr_src_0 <= SDAT_I(31 downto 0); -- 0x28 when "01010" => - blit_dimx_src_0 <= SDAT_I(31 downto 3) & "000"; + blit_reg_dimx_src_0 <= SDAT_I(31 downto 3) & "000"; -- sys_blit_descr_src_1 -- 0x30 when "01100" => - blit_addr_src_1 <= SDAT_I(31 downto 0); + blit_reg_addr_src_1 <= SDAT_I(31 downto 0); -- 0x38 when "01110" => - blit_dimx_src_1 <= SDAT_I(31 downto 3) & "000"; + blit_reg_dimx_src_1 <= SDAT_I(31 downto 3) & "000"; -- sys_blit_descr_dst -- 0x50 when "10100" => - blit_addr_dst <= SDAT_I(31 downto 0); + blit_reg_addr_dst <= SDAT_I(31 downto 0); - -- sys_blit_const_color + -- sys_blit_reg_const_color -- 0x54 when "10101" => - blit_const_color <= SDAT_I(31 downto 0); + blit_reg_const_color <= SDAT_I(31 downto 0); -- 0x58 when "10110" => - blit_dimx_dst <= SDAT_I(31 downto 3) & "000"; + blit_reg_dimx_dst <= SDAT_I(31 downto 3) & "000"; - -- sys_blit_nx + -- sys_blit_reg_nx -- 0x60 when "11000" => - blit_nx <= SDAT_I; + blit_reg_nx <= SDAT_I; - -- sys_blit_ny + -- sys_blit_reg_ny -- 0x64 when "11001" => - blit_ny <= SDAT_I; + blit_reg_ny <= SDAT_I; when others => null; end case;