Line 34... |
Line 34... |
entity gpuChip is
|
entity gpuChip is
|
|
|
generic(
|
generic(
|
FREQ : natural := 50_000; -- frequency of operation in KHz
|
FREQ : natural := 50_000; -- frequency of operation in KHz
|
PIPE_EN : boolean := true; -- enable fast, pipelined SDRAM operation
|
PIPE_EN : boolean := true; -- enable fast, pipelined SDRAM operation
|
MULTIPLE_ACTIVE_ROWS: boolean := true; -- if true, allow an active row in each bank
|
MULTIPLE_ACTIVE_ROWS: boolean := false; -- if true, allow an active row in each bank
|
CLK_DIV : real := 1.0; -- SDRAM Clock div
|
CLK_DIV : real := 1.0; -- SDRAM Clock div
|
NROWS : natural := 4096; -- number of rows in the SDRAM
|
NROWS : natural := 4096; -- number of rows in the SDRAM
|
NCOLS : natural := 512; -- number of columns in each SDRAM row
|
NCOLS : natural := 512; -- number of columns in each SDRAM row
|
SADDR_WIDTH : natural := 12;
|
SADDR_WIDTH : natural := 12;
|
DATA_WIDTH : natural := 16; -- SDRAM databus width
|
DATA_WIDTH : natural := 16; -- SDRAM databus width
|
ADDR_WIDTH : natural := 23; -- host-side address width
|
ADDR_WIDTH : natural := 24; -- host-side address width
|
VGA_CLK_DIV : natural := 4; -- pixel clock = FREQ / CLK_DIV
|
VGA_CLK_DIV : natural := 4; -- pixel clock = FREQ / CLK_DIV
|
PIXEL_WIDTH : natural := 8; -- width of a pixel in memory
|
PIXEL_WIDTH : natural := 8; -- width of a pixel in memory
|
NUM_RGB_BITS : natural := 2; -- #bits in each R,G,B component of a pixel
|
NUM_RGB_BITS : natural := 2; -- #bits in each R,G,B component of a pixel
|
PIXELS_PER_LINE : natural := 320; -- width of image in pixels
|
PIXELS_PER_LINE : natural := 320; -- width of image in pixels
|
LINES_PER_FRAME : natural := 240; -- height of image in scanlines
|
LINES_PER_FRAME : natural := 240; -- height of image in scanlines
|
Line 55... |
Line 55... |
port(
|
port(
|
pin_clkin : in std_logic; -- main clock input from external clock source
|
pin_clkin : in std_logic; -- main clock input from external clock source
|
pin_ce_n : out std_logic; -- Flash RAM chip-enable
|
pin_ce_n : out std_logic; -- Flash RAM chip-enable
|
pin_pushbtn : in std_logic;
|
pin_pushbtn : in std_logic;
|
|
|
|
|
|
-- blitter port connections
|
|
pin_port_in : in std_logic_vector (7 downto 0);
|
|
pin_port_addr : in std_logic_vector (3 downto 0);
|
|
pin_load : in std_logic;
|
|
pin_start : in std_logic;
|
|
pin_done : out std_logic;
|
|
pin_flip_buffer: in std_logic;
|
|
|
-- vga port connections
|
-- vga port connections
|
pin_red : out std_logic_vector(1 downto 0);
|
pin_red : out std_logic_vector(1 downto 0);
|
pin_green : out std_logic_vector(1 downto 0);
|
pin_green : out std_logic_vector(1 downto 0);
|
pin_blue : out std_logic_vector(1 downto 0);
|
pin_blue : out std_logic_vector(1 downto 0);
|
pin_hsync_n : out std_logic;
|
pin_hsync_n : out std_logic;
|
Line 87... |
Line 96... |
constant HI: std_logic := '1';
|
constant HI: std_logic := '1';
|
constant LO: std_logic := '0';
|
constant LO: std_logic := '0';
|
|
|
type gpuState is (
|
type gpuState is (
|
INIT, -- init
|
INIT, -- init
|
INIT_BKG,
|
LOAD,
|
DRAW_BKG,
|
DRAW,
|
BLIT_REST,
|
REST
|
INIT_SPRITE,
|
|
DRAW_SPRITE,
|
|
UPDATE
|
|
);
|
);
|
|
|
signal state_r, state_x : gpuState; -- state register and next state
|
signal state_r, state_x : gpuState; -- state register and next state
|
|
|
--registers
|
--registers
|
signal plane0_dest_r, plane0_dest_x : std_logic_vector (ADDR_WIDTH - 1 downto 0); -- sprite dest register
|
signal source_address_x, source_address_r : std_logic_vector (ADDR_WIDTH - 1 downto 0); -- sprite dest register
|
signal plane0_ypos_r, plane0_ypos_x : std_logic_vector (11 downto 0);
|
|
signal delay_r, delay_x : std_logic_vector (19 downto 0); --20 bit counter for delay
|
|
signal source_address_x, source_address_r : std_logic_vector (ADDR_WIDTH -1 downto 0);
|
|
signal target_address_x, target_address_r : std_logic_vector (ADDR_WIDTH -1 downto 0);
|
signal target_address_x, target_address_r : std_logic_vector (ADDR_WIDTH -1 downto 0);
|
signal line_size_x, line_size_r : std_logic_vector (11 downto 0);
|
|
signal source_lines_x, source_lines_r : std_logic_vector (15 downto 0);
|
signal source_lines_x, source_lines_r : std_logic_vector (15 downto 0);
|
|
signal line_size_x, line_size_r : std_logic_vector (11 downto 0);
|
signal alphaOp_x, alphaOp_r : std_logic;
|
signal alphaOp_x, alphaOp_r : std_logic;
|
signal front_buffer_x, front_buffer_r : std_logic;
|
signal front_buffer_x, front_buffer_r : std_logic;
|
|
signal idle_x, idle_r : std_logic;
|
|
--signal flip_buf_pend_x, flip_buf_pend_r : std_logic;
|
|
|
--internal signals
|
--internal signals
|
signal sysReset : std_logic; -- system reset
|
signal sysReset : std_logic; -- system reset
|
signal blit_reset : std_logic;
|
signal blit_reset : std_logic;
|
signal reset_blitter : std_logic;
|
signal reset_blitter : std_logic;
|
Line 123... |
Line 128... |
signal target_address : std_logic_vector(ADDR_WIDTH-1 downto 0);
|
signal target_address : std_logic_vector(ADDR_WIDTH-1 downto 0);
|
signal blit_done : std_logic;
|
signal blit_done : std_logic;
|
signal alphaOp : std_logic;
|
signal alphaOp : std_logic;
|
signal front_buffer : std_logic;
|
signal front_buffer : std_logic;
|
|
|
|
signal port_in : std_logic_vector (7 downto 0);
|
|
signal port_addr : std_logic_vector (3 downto 0);
|
|
|
--Application Side Signals for the DualPort Controller
|
--Application Side Signals for the DualPort Controller
|
signal rst_i : std_logic; --tied reset signal
|
signal rst_i : std_logic; --tied reset signal
|
signal opBegun0, opBegun1 : std_logic; -- read/write operation started indicator
|
signal opBegun0, opBegun1 : std_logic; -- read/write operation started indicator
|
signal earlyOpBegun0, earlyOpBegun1 : std_logic; -- read/write operation started indicator
|
signal earlyOpBegun0, earlyOpBegun1 : std_logic; -- read/write operation started indicator
|
signal rdPending0, rdPending1 : std_logic; -- read operation pending in SDRAM pipeline indicator
|
signal rdPending0, rdPending1 : std_logic; -- read operation pending in SDRAM pipeline indicator
|
Line 363... |
Line 371... |
blit_reset <= rst_i or reset_blitter;
|
blit_reset <= rst_i or reset_blitter;
|
|
|
-- Port0 is reserved for VGA
|
-- Port0 is reserved for VGA
|
pixels <= hDOut0 when drawframe = '1' else "0000000000000000";
|
pixels <= hDOut0 when drawframe = '1' else "0000000000000000";
|
|
|
|
port_in <= pin_port_in;
|
|
port_addr <= pin_port_addr;
|
|
pin_done <= idle_r;
|
|
|
source_address <= source_address_r;
|
source_address <= source_address_r;
|
line_size <= line_size_r;
|
line_size <= line_size_r;
|
target_address <= target_address_r;
|
target_address <= target_address_r;
|
source_lines <= source_lines_r;
|
source_lines <= source_lines_r;
|
alphaOp <= alphaOp_r;
|
alphaOp <= alphaOp_r;
|
|
|
front_buffer <= YES;--front_buffer_r;
|
front_buffer <= YES;--front_buffer_r;
|
|
|
comb:process(state_r, delay_r, plane0_dest_r)
|
comb:process(state_r, port_in, port_addr, pin_start)
|
begin
|
begin
|
blit_begin <= NO; --default operations
|
blit_begin <= NO; --default operations
|
reset_blitter <= NO;
|
reset_blitter <= NO;
|
|
|
state_x <= state_r; --default register values
|
state_x <= state_r; --default register values
|
delay_x <= delay_r + 1;
|
|
source_address_x <= source_address_r;
|
source_address_x <= source_address_r;
|
line_size_x <= line_size_r;
|
|
target_address_x <= target_address_r;
|
target_address_x <= target_address_r;
|
source_lines_x <= source_lines_r;
|
source_lines_x <= source_lines_r;
|
|
line_size_x <= line_size_r;
|
alphaOp_x <= alphaOp_r;
|
alphaOp_x <= alphaOp_r;
|
plane0_dest_x <= plane0_dest_r;
|
|
plane0_ypos_x <= plane0_ypos_r;
|
|
front_buffer_x <= front_buffer_r;
|
front_buffer_x <= front_buffer_r;
|
|
idle_x <= idle_r;
|
|
|
case state_r is
|
case state_r is
|
when INIT =>
|
when INIT =>
|
blit_begin <= NO;
|
idle_x <= YES;
|
reset_blitter <= YES;
|
reset_blitter <= YES;
|
state_x <= INIT_BKG;
|
state_x <= LOAD;
|
plane0_dest_x <= x"000060";
|
|
plane0_ypos_x <= x"000";
|
|
front_buffer_x <= YES;
|
|
|
|
when INIT_BKG =>
|
|
--flip buffers
|
|
source_address_x <= x"012C00";
|
|
line_size_x <= x"0A0";
|
|
target_address_x <= x"000000";
|
|
source_lines_x <= x"00EF";
|
|
alphaOp_x <= NO;
|
|
blit_begin <= YES;
|
|
state_x <= DRAW_BKG;
|
|
|
|
when DRAW_BKG =>
|
when LOAD =>
|
blit_begin <= YES;
|
if (pin_load = YES) then
|
|
case port_addr is
|
if (blit_done = YES) then
|
when "0000" => source_address_x(23 downto 16) <= port_in;
|
reset_blitter <= YES;
|
when "0001" => source_address_x(15 downto 8) <= port_in;
|
state_x <= BLIT_REST;
|
when "0010" => source_address_x(7 downto 0) <= port_in;
|
|
when "0011" => target_address_x(23 downto 16) <= port_in;
|
|
when "0100" => target_address_x(15 downto 8) <= port_in;
|
|
when "0101" => target_address_x(7 downto 0) <= port_in;
|
|
when "0110" => source_lines_x (15 downto 8) <= port_in;
|
|
when "0111" => source_lines_x (7 downto 0) <= port_in;
|
|
when "1000" => line_size_x (11 downto 8) <= port_in(3 downto 0);
|
|
when "1001" => line_size_x (7 downto 0) <= port_in;
|
|
when "1010" => alphaOp_x <= port_in(0);
|
|
when others =>
|
|
end case;
|
end if;
|
end if;
|
|
|
when BLIT_REST =>
|
if (pin_start = YES) then
|
source_address_x <= x"01EBE5";
|
idle_x <= NO;
|
line_size_x <= x"024";
|
state_x <= DRAW;
|
target_address_x <= plane0_dest_r;
|
end if;
|
source_lines_x <= x"004E";
|
|
alphaOp_x <= YES;
|
|
|
|
reset_blitter <= YES;
|
|
state_x <= INIT_SPRITE;
|
|
|
|
when INIT_SPRITE =>
|
|
blit_begin <= YES;
|
|
|
|
state_x <= DRAW_SPRITE;
|
|
|
|
when DRAW_SPRITE =>
|
when DRAW =>
|
blit_begin <= YES;
|
blit_begin <= YES;
|
|
|
if (blit_done = YES) then
|
if (blit_done = YES) then
|
reset_blitter <= YES;
|
reset_blitter <= YES;
|
state_x <= UPDATE;
|
idle_x <= YES;
|
|
state_x <= REST;
|
end if;
|
end if;
|
|
|
when UPDATE =>
|
when REST =>
|
reset_blitter <= YES;
|
reset_blitter <= YES;
|
if (delay_r = x"FFFFF") then
|
state_x <= LOAD;
|
plane0_dest_x <= plane0_dest_r + x"000140";
|
|
plane0_ypos_x <= plane0_ypos_r + x"001";
|
|
if (plane0_ypos_r = x"050") then
|
|
plane0_dest_x <= x"000060";
|
|
plane0_ypos_x <= x"000";
|
|
end if;
|
|
state_x <= INIT_BKG;
|
|
end if;
|
|
|
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
-- update the SDRAM address counter
|
-- update the SDRAM address counter
|
Line 464... |
Line 454... |
|
|
-- reset the address at the end of a video frame depending on which buffer is the front
|
-- reset the address at the end of a video frame depending on which buffer is the front
|
if (front_buffer = YES) then
|
if (front_buffer = YES) then
|
vga_address <= x"000000";
|
vga_address <= x"000000";
|
else
|
else
|
vga_address <= x"009600";
|
vga_address <= x"000000"; --temporary
|
end if;
|
end if;
|
|
|
elsif (earlyOpBegun0 = YES) then
|
elsif (earlyOpBegun0 = YES) then
|
vga_address <= vga_address + 1; -- go to the next address once the read of the current address has begun
|
vga_address <= vga_address + 1; -- go to the next address once the read of the current address has begun
|
end if;
|
end if;
|
|
|
--reset stuff
|
--reset stuff
|
if (sysReset = YES) then
|
if (sysReset = YES) then
|
state_r <= INIT;
|
state_r <= INIT;
|
end if;
|
end if;
|
|
|
state_r <= state_x;
|
state_r <= state_x;
|
delay_r <= delay_x;
|
|
source_address_r <= source_address_x;
|
source_address_r <= source_address_x;
|
line_size_r <= line_size_x;
|
|
target_address_r <= target_address_x;
|
target_address_r <= target_address_x;
|
source_lines_r <= source_lines_x;
|
source_lines_r <= source_lines_x;
|
|
line_size_r <= line_size_x;
|
alphaOp_r <= alphaOp_x;
|
alphaOp_r <= alphaOp_x;
|
plane0_dest_r <= plane0_dest_x;
|
|
plane0_ypos_r <= plane0_ypos_x;
|
|
front_buffer_r <= front_buffer_x;
|
front_buffer_r <= front_buffer_x;
|
|
idle_r <= idle_x;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
--process reset circuitry
|
--process reset circuitry
|