Line 7... |
Line 7... |
--Eric Sands
|
--Eric Sands
|
--
|
--
|
--of the University of Illinois at Urbana Champaign
|
--of the University of Illinois at Urbana Champaign
|
--under the direction of Dr. Lippold Haken
|
--under the direction of Dr. Lippold Haken
|
--====================================================
|
--====================================================
|
|
--
|
|
--Heavily based off of HDL examples provided by XESS Corporation
|
|
--www.xess.com
|
|
--
|
--Based in part on Doug Hodson's work which in turn
|
--Based in part on Doug Hodson's work which in turn
|
--was based off of the XSOC from Gray Research LLC.
|
--was based off of the XSOC from Gray Research LLC.
|
--
|
--
|
|
--
|
--release under the GNU General Public License
|
--release under the GNU General Public License
|
--and kindly hosted by www.opencores.org
|
--and kindly hosted by www.opencores.org
|
|
|
|
|
library IEEE;
|
library IEEE;
|
Line 21... |
Line 26... |
use IEEE.std_logic_unsigned.all;
|
use IEEE.std_logic_unsigned.all;
|
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
use WORK.common.all;
|
use WORK.common.all;
|
use WORK.xsasdram.all;
|
use WORK.xsasdram.all;
|
use WORK.sdram.all;
|
use WORK.sdram.all;
|
|
use WORK.vga_pckg.all;
|
|
|
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
|
CLK_DIV : real := 1.0; -- divisor for FREQ (can only be 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
|
|
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 := true; -- if true, allow an active row in each bank
|
|
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 := 256; -- number of columns in each SDRAM row
|
SADDR_WIDTH : natural := 12;
|
SADDR_WIDTH : natural := 12;
|
|
DATA_WIDTH : natural := 16; -- SDRAM databus width
|
|
ADDR_WIDTH : natural := 22; -- host-side address width
|
|
VGA_CLK_DIV : natural := 1; -- pixel clock = FREQ / CLK_DIV
|
|
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
|
|
PIXELS_PER_LINE : natural := 800; -- width of image in pixels
|
|
LINES_PER_FRAME : natural := 600; -- height of image in scanlines
|
|
FIT_TO_SCREEN : boolean := true; -- adapt video timing to fit image width x
|
PORT_TIME_SLOTS : std_logic_vector(15 downto 0) := "0000000000000000"
|
PORT_TIME_SLOTS : std_logic_vector(15 downto 0) := "0000000000000000"
|
);
|
);
|
|
|
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
|
Line 72... |
Line 84... |
constant YES: std_logic := '1';
|
constant YES: std_logic := '1';
|
constant NO: std_logic := '0';
|
constant NO: std_logic := '0';
|
constant HI: std_logic := '1';
|
constant HI: std_logic := '1';
|
constant LO: std_logic := '0';
|
constant LO: std_logic := '0';
|
|
|
constant DATA_WIDTH: natural := 16;
|
|
constant ADDR_WIDTH: natural := 23;
|
|
|
|
-- memory state management variables
|
|
type VGAStateType is (
|
|
VGA_IDLE, -- finished just waiting for a request
|
|
VGA_READ0, -- Buffer states which may or may not all be executed
|
|
VGA_READ1,
|
|
VGA_READ2,
|
|
VGA_READ3
|
|
--VGA_READ4,
|
|
--VGA_READ5,
|
|
--VGA_READ6,
|
|
--VGA_READ7
|
|
);
|
|
|
|
--internal signals
|
--internal signals
|
signal VGAState_r, VGAState_nxt: VGAStateType;
|
|
signal hAddr_r, hAddr_nxt : std_logic_vector (ADDR_WIDTH-1 downto 0); -- host address bus
|
|
|
|
signal sysClk : std_logic; -- system clock
|
signal sysClk : std_logic; -- system clock
|
signal sysReset : std_logic; -- system reset
|
signal sysReset : std_logic; -- system reset
|
|
|
signal int_clk_by2 : std_logic; --intermediate clock (divide by 2)
|
signal int_clk_by2 : std_logic; --intermediate clock (divide by 2)
|
signal int_clk_by4 : std_logic; --intermediate clock (divide by 4)
|
signal int_clk_by4 : std_logic; --intermediate clock (divide by 4)
|
Line 110... |
Line 103... |
signal hAddr0, hAddr1 : std_logic_vector(ADDR_WIDTH-1 downto 0); -- host-side address bus
|
signal hAddr0, hAddr1 : std_logic_vector(ADDR_WIDTH-1 downto 0); -- host-side address bus
|
signal hDIn0, hDIn1 : std_logic_vector(DATA_WIDTH-1 downto 0); -- host-side data to SDRAM
|
signal hDIn0, hDIn1 : std_logic_vector(DATA_WIDTH-1 downto 0); -- host-side data to SDRAM
|
signal hDOut0, hDOut1 : std_logic_vector(DATA_WIDTH-1 downto 0); -- host-side data from SDRAM
|
signal hDOut0, hDOut1 : std_logic_vector(DATA_WIDTH-1 downto 0); -- host-side data from SDRAM
|
signal rd0, rd1 : std_logic; -- host-side read control signal
|
signal rd0, rd1 : std_logic; -- host-side read control signal
|
signal wr0, wr1 : std_logic; -- host-side write control signal
|
signal wr0, wr1 : std_logic; -- host-side write control signal
|
|
|
-- SDRAM host side signals
|
-- SDRAM host side signals
|
signal sdram_bufclk : std_logic; -- buffered input (non-DLL) clock
|
signal sdram_bufclk : std_logic; -- buffered input (non-DLL) clock
|
signal sdram_clk1x : std_logic; -- internal master clock signal
|
signal sdram_clk1x : std_logic; -- internal master clock signal
|
signal sdram_clk2x : std_logic; -- doubled clock
|
signal sdram_clk2x : std_logic; -- doubled clock
|
signal sdram_lock : std_logic; -- SDRAM clock DLL lock indicator
|
signal sdram_lock : std_logic; -- SDRAM clock DLL lock indicator
|
Line 127... |
Line 121... |
signal sdram_rdDone : std_logic; -- host-side read completed signal
|
signal sdram_rdDone : std_logic; -- host-side read completed signal
|
signal sdram_hAddr : std_logic_vector(ADDR_WIDTH -1 downto 0); -- host address bus
|
signal sdram_hAddr : std_logic_vector(ADDR_WIDTH -1 downto 0); -- host address bus
|
signal sdram_hDIn : std_logic_vector(DATA_WIDTH -1 downto 0); -- host-side data to SDRAM
|
signal sdram_hDIn : std_logic_vector(DATA_WIDTH -1 downto 0); -- host-side data to SDRAM
|
signal sdram_hDOut : std_logic_vector(DATA_WIDTH -1 downto 0); -- host-side data from SDRAM
|
signal sdram_hDOut : std_logic_vector(DATA_WIDTH -1 downto 0); -- host-side data from SDRAM
|
signal sdram_status : std_logic_vector(3 downto 0); -- SDRAM controller status
|
signal sdram_status : std_logic_vector(3 downto 0); -- SDRAM controller status
|
-- vga signals
|
|
signal vga_clk : std_logic; -- global clock
|
|
signal vga_vack : std_logic; -- video data DMA acknowledge
|
|
signal vga_pixels_in : std_logic_vector(15 downto 0); -- video data in
|
|
signal vga_vreq : std_logic; -- video data DMA request
|
|
signal vga_vreset : std_logic; -- video data reset DMA counter request
|
|
--Need to reiterate the VGA component as it is written in Verilog
|
|
component vga
|
|
port(
|
|
clk: in std_logic; -- global clock
|
|
rst: in std_logic; -- global async reset
|
|
vack: in std_logic; -- video data DMA acknowledge
|
|
pixels_in: in std_logic_vector(15 downto 0); -- video data in
|
|
vreq: out std_logic; -- video data DMA request
|
|
vreset: out std_logic; -- video data reset DMA counter request
|
|
hsync_n: out std_logic; -- active low horz sync
|
|
vsync_n: out std_logic; -- active low vert sync
|
|
r: out std_logic_vector(1 downto 0); -- red
|
|
g: out std_logic_vector(1 downto 0); -- green
|
|
b: out std_logic_vector(1 downto 0) -- blue
|
|
);
|
|
end component;
|
|
|
|
|
|
|
-- VGA related signals
|
|
signal eof : std_logic; -- end-of-frame signal from VGA controller
|
|
signal full : std_logic; -- indicates when the VGA pixel buffer is full
|
|
signal vga_address : unsigned(ADDR_WIDTH-1 downto 0); -- SDRAM address counter
|
|
signal rst_n : std_logic; --VGA reset (active low)
|
--------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------
|
-- Beginning of Submodules
|
-- Beginning of Submodules
|
-- All instances of submodules and signals associated with them
|
-- All instances of submodules and signals associated with them
|
-- are declared within. Signals not directly associated with
|
-- are declared within. Signals not directly associated with
|
-- submodules are declared elsewhere.
|
-- submodules are declared elsewhere.
|
Line 270... |
Line 248... |
|
|
|
|
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
-- Instantiate the VGA module
|
-- Instantiate the VGA module
|
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
-- Instance Module
|
|
u3: vga
|
u3: vga
|
|
generic map (
|
|
FREQ => FREQ,
|
|
CLK_DIV => VGA_CLK_DIV,
|
|
PIXEL_WIDTH => PIXEL_WIDTH,
|
|
PIXELS_PER_LINE => PIXELS_PER_LINE,
|
|
LINES_PER_FRAME => LINES_PER_FRAME,
|
|
NUM_RGB_BITS => NUM_RGB_BITS,
|
|
FIT_TO_SCREEN => FIT_TO_SCREEN
|
|
)
|
port map(
|
port map(
|
clk => vga_clk,
|
rst => rst_i,
|
rst => sysReset,
|
clk => sdram_clk1x, -- use the resync'ed master clock so VGA generator is in sync with SDRAM
|
vack => vga_vack,
|
wr => rdDone0, -- write to pixel buffer when the data read from SDRAM is available
|
pixels_in => vga_pixels_in,
|
pixel_data_in => hDOut0, -- pixel data from SDRAM
|
vreq => vga_vreq,
|
full => full, -- indicates when the pixel buffer is full
|
vreset => vga_vreset,
|
eof => eof, -- indicates when the VGA generator has finished a video frame
|
hsync_n => pin_hsync_n,
|
r => pin_red, -- RGB components (output)
|
vsync_n => pin_vsync_n,
|
|
r => pin_red,
|
|
g => pin_green,
|
g => pin_green,
|
b => pin_blue
|
b => pin_blue,
|
|
hsync_n => pin_hsync_n, -- horizontal sync
|
|
vsync_n => pin_vsync_n, -- vertical sync
|
|
blank => open
|
);
|
);
|
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------
|
-- End of Submodules
|
-- End of Submodules
|
--------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------
|
-- Begin Top Level Module
|
-- Begin Top Level Module
|
|
|
sysClk <= sdram_clk1x; -- use SDRAM_CLK1X as the system clock
|
|
rst_i <= sysReset;
|
rst_i <= sysReset;
|
pin_ce_n <= '1'; -- disable Flash RAM
|
pin_ce_n <= '1'; -- disable Flash RAM
|
|
rd0 <= not full; -- negate the full signal for use in controlling the SDRAM read operation
|
|
hDIn0 <= "0000000000000000000000";
|
|
wr0 <= '0';
|
|
hAddr0 <= std_logic_vector(vga_address);
|
|
|
-- cascaded clock dividers
|
|
process(sysClk)
|
|
begin
|
|
if (rising_edge(sysClk)) then
|
|
if (int_clk_by2 = HI) then
|
|
int_clk_by2 <= LO;
|
|
else
|
|
int_clk_by2 <= HI;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
process(int_clk_by2)
|
|
begin
|
|
if (rising_edge(int_clk_by2)) then
|
|
if (vga_clk = HI) then
|
|
vga_clk <= LO;
|
|
else
|
|
vga_clk <= HI;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
--
|
--
|
|
-- -- cascaded clock dividers
|
|
-- process(sysClk)
|
|
-- begin
|
|
-- if (rising_edge(sysClk)) then
|
|
-- if (int_clk_by2 = HI) then
|
|
-- int_clk_by2 <= LO;
|
|
-- else
|
|
-- int_clk_by2 <= HI;
|
|
-- end if;
|
|
-- end if;
|
|
-- end process;
|
--
|
--
|
-- process(int_clk_by4)
|
-- process(int_clk_by2)
|
-- begin
|
-- begin
|
-- if (rising_edge(int_clk_by4)) then
|
-- if (rising_edge(int_clk_by2)) then
|
-- if (vga_clk = HI) then
|
-- if (vga_clk = HI) then
|
-- vga_clk <= LO;
|
-- vga_clk <= LO;
|
-- else
|
-- else
|
-- vga_clk <= HI;
|
-- vga_clk <= HI;
|
-- end if;
|
-- end if;
|
-- end if;
|
-- end if;
|
-- end process;
|
-- end process;
|
--
|
|
-- connect internal registers to external busses
|
-- connect internal registers to external busses
|
-- Port1 is reserved for VGA
|
-- Port1 is reserved for VGA
|
hAddr0 <= hAddr_r; -- memory address bus driven by memory address register
|
|
vga_pixels_in <= hDOut0;
|
|
|
|
-- memory controller state machine
|
-- update the SDRAM address counter
|
-- "process" the change in status of various signals
|
process(sdram_clk1x)
|
|
|
process(sysReset, VGAState_r, done0, vga_vreq, vga_vreset)
|
|
begin
|
begin
|
|
if rising_edge(sdram_clk1x) then
|
-- have we been reset?
|
if eof = YES then
|
if (sysReset = YES) then
|
vga_address <= "0000000000000000000000"; -- reset the address at the end of a video frame
|
VGAState_nxt <= VGA_IDLE;
|
elsif earlyOpBegun0 = YES then
|
hAddr_nxt <= "00000000000000000000000";
|
vga_address <= vga_address + 1; -- go to the next address once the read of the current address has begun
|
rd0 <= NO;
|
|
vga_vack <= NO;
|
|
else
|
|
rd0 <= NO; -- default no memory read
|
|
wr0 <= NO; -- default no memory write
|
|
vga_vack <= NO; -- default no ack of new data to vga circuit
|
|
VGAState_nxt <= VGAState_r;
|
|
hAddr_nxt <= hAddr_r; -- next address is the same as current address
|
|
|
|
if (vga_vreset = YES) then -- reset address?
|
|
hAddr_nxt <= "00000000000000000000000";
|
|
end if;
|
|
|
|
case VGAState_r is
|
|
|
|
-- memory idle, just waiting around for a request
|
|
when VGA_IDLE =>
|
|
if (vga_vreq = YES) then
|
|
vga_vack <= NO;
|
|
VGAState_nxt <= VGA_READ0; -- move to read state
|
|
end if;
|
|
|
|
-- read from memory
|
|
when VGA_READ0 =>
|
|
rd0 <= YES; -- keep asserting read signal
|
|
if (done0 = YES) then
|
|
vga_vack <= YES;
|
|
VGAState_nxt <= VGA_READ1;
|
|
end if;
|
end if;
|
|
|
when VGA_READ1 =>
|
|
rd0 <= YES;
|
|
vga_vack <= YES;
|
|
VGAState_nxt <= VGA_READ2;
|
|
|
|
when VGA_READ2 =>
|
|
rd0 <= YES;
|
|
vga_vack <= YES;
|
|
VGAState_nxt <= VGA_READ3;
|
|
|
|
when VGA_READ3 =>
|
|
rd0 <= YES;
|
|
vga_vack <= YES;
|
|
hAddr_nxt <= hAddr_r + 1; -- increment address counter
|
|
VGAState_nxt <= VGA_IDLE; -- whole state machine is synchronized to
|
|
-- VGA_clk
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
process(sysClk, sysReset)
|
|
begin
|
|
if (sysReset=YES) then
|
|
VGAState_r <= VGA_IDLE;
|
|
hAddr_r <= "00000000000000000000000";
|
|
elsif (rising_edge(sysClk)) then
|
|
VGAState_r <= VGAState_nxt;
|
|
hAddr_r <= hAddr_nxt;
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- synchronous reset. internal reset flag is set active by config. bitstream
|
|
-- and then gets reset after DLL clocks start.
|
|
process(sdram_bufclk)
|
process(sdram_bufclk)
|
begin
|
begin
|
if (rising_edge(sdram_bufclk)) then
|
if (rising_edge(sdram_bufclk)) then
|
if sdram_lock='0' then
|
if sdram_lock='0' then
|
sysReset <= '1'; -- keep in reset until DLLs start up
|
sysReset <= '1'; -- keep in reset until DLLs start up
|
Line 421... |
Line 335... |
sysReset <= not pin_pushbtn; -- push button will reset
|
sysReset <= not pin_pushbtn; -- push button will reset
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
end arch;
|
end arch;
|
No newline at end of file
|
No newline at end of file
|