📄 chipio.vhd
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--
-- xsocVGABitmap Example Project
-- Doug Hodson, Jun 2003
-- www.RetroMicro.com
--
-- Run design at 25 MHz
--
entity chipIO is
port(
pin_clkin : in std_logic; -- main clock input from external clock source
pin_ce_n : out std_logic; -- Flash RAM chip-enable
pin_pushbtn : in std_logic;
-- vga port connections
pin_red : 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_hsync_n : out std_logic;
pin_vsync_n : out std_logic;
-- SDRAM pin connections
pin_sclkfb : in std_logic; -- feedback SDRAM clock with PCB delays
pin_sclk : out std_logic; -- clock to SDRAM
pin_cke : out std_logic; -- SDRAM clock-enable
pin_cs_n : out std_logic; -- SDRAM chip-select
pin_ras_n : out std_logic; -- SDRAM RAS
pin_cas_n : out std_logic; -- SDRAM CAS
pin_we_n : out std_logic; -- SDRAM write-enable
pin_ba : out unsigned( 1 downto 0); -- SDRAM bank-address
pin_sAddr : out unsigned(11 downto 0); -- SDRAM address bus
pin_sData : inout unsigned(16-1 downto 0); -- data bus to SDRAM
pin_dqmh : out std_logic; -- SDRAM DQMH
pin_dqml : out std_logic -- SDRAM DQML
);
end chipIO;
architecture arch of chipIO is
constant YES: std_logic := '1';
constant NO: std_logic := '0';
constant HI: std_logic := '1';
constant LO: std_logic := '0';
constant DATA_WIDTH: natural := 16;
constant ADDR_WIDTH: natural := 23;
signal sysClk : std_logic; -- system clock
signal sysReset : std_logic; -- system reset
-- vga component
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 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
component sdramCntl
generic(
FREQ: natural := 25_000; -- operating frequency in KHz
DATA_WIDTH: natural := 16; -- host & SDRAM data width
NROWS: natural := 4096; -- number of rows in SDRAM array
NCOLS: natural := 512; -- number of columns in SDRAM array
HADDR_WIDTH: natural := 23; -- host-side address width
SADDR_WIDTH: natural := 12 -- SDRAM-side address width
);
port(
clkin: in std_logic; -- master clock
-- host side
bufclk: out std_logic; -- buffered master clock
clk0: out std_logic; -- host clock sync'ed to master clock
clk2x: out std_logic; -- double-speed host clock
lock: out std_logic; -- indicate when clock circuitry is locked to master clock
rst: in std_logic; -- reset
rd: in std_logic; -- read data
wr: in std_logic; -- write data
done: out std_logic; -- read/write op done
hAddr: in unsigned(HADDR_WIDTH-1 downto 0); -- address from host
hDIn: in unsigned(DATA_WIDTH-1 downto 0); -- data from host
hDOut: out unsigned(DATA_WIDTH-1 downto 0); -- data to host
sdramCntl_state: out std_logic_vector(3 downto 0);
-- SDRAM side
sclkfb: in std_logic; -- clock from SDRAM after PCB delays
sclk: out std_logic; -- SDRAM clock sync'ed to master clock
cke: out std_logic; -- clock-enable to SDRAM
cs_n: out std_logic; -- chip-select to SDRAM
ras_n: out std_logic; -- command input to SDRAM
cas_n: out std_logic; -- command input to SDRAM
we_n: out std_logic; -- command input to SDRAM
ba: out unsigned(1 downto 0); -- SDRAM bank address bits
sAddr: out unsigned(SADDR_WIDTH-1 downto 0); -- SDRAM row/column address
sData: inout unsigned(DATA_WIDTH-1 downto 0); -- SDRAM in/out databus
dqmh: out std_logic; -- high databits I/O mask
dqml: out std_logic -- low databits I/O mask
);
end component;
-- SDRAM host side signals
signal sdram_bufclk : std_logic; -- buffered input (non-DLL) clock
signal sdram_clk0 : std_logic; -- internal master clock signal
signal sdram_lock : std_logic; -- SDRAM clock DLL lock indicator
signal sdram_rst : std_logic; -- internal reset signal
signal sdram_rd : std_logic; -- host-side read control signal
signal sdram_wr : std_logic; -- host-side write control signal
signal sdram_done : std_logic; -- SDRAM operation complete indicator
signal sdram_hAddr : unsigned(ADDR_WIDTH-1 downto 0); -- host address bus
signal sdram_hDIn : unsigned(DATA_WIDTH-1 downto 0); -- host-side data to SDRAM
signal sdram_hDOut : unsigned(DATA_WIDTH-1 downto 0); -- host-side data from SDRAM
-- memory state management variables
type memoryStateType is (
MEMORY_IDLE, -- finished just waiting for a request
MEMORY_READ, -- need to execute a read transaction
MEMORY_WAIT_FOR_VGA -- needed to add one additional cycle for vga circuit
);
signal memoryState_r, memoryState_nxt: memoryStateType;
signal hAddr_r, hAddr_nxt : unsigned(ADDR_WIDTH-1 downto 0); -- host address bus
begin
pin_ce_n <= '1'; -- disable Flash RAM
-- connect internal registers to external busses
sdram_hAddr <= hAddr_r; -- memory address bus driven by memory address register
-- memory controller state machine
-- "process" the change in status of various signals
process(sysReset, memoryState_r, sdram_done, vga_vreq, vga_vreset)
begin
-- have we been reset?
if (sysReset = YES) then
memoryState_nxt <= MEMORY_IDLE;
hAddr_nxt <= "00000000000000000000000";
else
sdram_rd <= NO; -- default no memory read
sdram_wr <= NO; -- default no memory write
vga_vack <= NO; -- default no ack of new data to vga circuit
memoryState_nxt <= memoryState_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 memoryState_r is
-- memory idle, just waiting around for a request
when MEMORY_IDLE =>
if (vga_vreq = YES) then
vga_vack <= NO;
memoryState_nxt <= MEMORY_READ; -- more to read state
end if;
-- read from memory
when MEMORY_READ =>
sdram_rd <= YES; -- keep asserting read signal
if (sdram_done = YES) then
vga_pixels_in <= std_logic_vector(sdram_hDOut);
vga_vack <= YES;
memoryState_nxt <= MEMORY_WAIT_FOR_VGA; -- one cycle delay
end if;
-- gives the vga circuit one extra cycle (remember it's running at half
-- the clock rate of sdram controller) to grab data
when MEMORY_WAIT_FOR_VGA =>
vga_pixels_in <= std_logic_vector(sdram_hDOut);
vga_vack <= YES;
hAddr_nxt <= hAddr_r + 1; -- increment address counter
memoryState_nxt <= MEMORY_IDLE; -- move to idle state
end case;
end if;
end process;
-- keep on move'n, don't stop!
process(sysClk, sysReset)
begin
if (sysReset=YES) then
memoryState_r <= MEMORY_IDLE;
hAddr_r <= "00000000000000000000000";
elsif (rising_edge(sysClk)) then
memoryState_r <= memoryState_nxt;
hAddr_r <= hAddr_nxt;
end if;
end process;
-- vga component
u1: vga
port map(
clk => vga_clk,
rst => sysReset,
vack => vga_vack,
pixels_in => vga_pixels_in,
vreq => vga_vreq,
vreset => vga_vreset,
hsync_n => pin_hsync_n,
vsync_n => pin_vsync_n,
r => pin_red,
g => pin_green,
b => pin_blue
);
-- simple clock divider
process(sysClk)
begin
if (rising_edge(sysClk)) then
if (vga_clk=HI) then
vga_clk <= LO;
else
vga_clk <= HI;
end if;
end if;
end process;
-- SDRAM memory controller module
u2: sdramCntl
generic map(
FREQ => 25_000, -- 25 MHz operation
DATA_WIDTH => 16,
NROWS => 4096,
NCOLS => 512,
HADDR_WIDTH => 23,
SADDR_WIDTH => 12
)
port map(
clkin => pin_clkin, -- master clock from external clock source (unbuffered)
bufclk => sdram_bufclk, -- buffered master clock output
clk0 => sysClk, -- synchronized master clock (accounts for delays to external SDRAM)
clk2x => open, -- synchronized doubled master clock
lock => sdram_lock, -- valid synchronized clocks indicator
rst => sysReset, -- reset
rd => sdram_rd, -- host-side SDRAM read control from memory tester
wr => sdram_wr, -- host-side SDRAM write control from memory tester
done => sdram_done, -- SDRAM memory read/write done indicator
hAddr => sdram_hAddr, -- host-side address from memory tester
hDIn => sdram_hDIn, -- always send data from xsoc to memory
hDOut => sdram_hDOut, -- SDRAM data output to memory tester
sdramCntl_state => open, -- SDRAM controller state (for diagnostics)
-- SDRAM side
sclkfb => pin_sclkfb, -- clock feedback with added external PCB delays
sclk => pin_sclk, -- synchronized clock to external SDRAM
cke => pin_cke, -- SDRAM clock enable
cs_n => pin_cs_n, -- SDRAM chip-select
ras_n => pin_ras_n, -- SDRAM RAS
cas_n => pin_cas_n, -- SDRAM CAS
we_n => pin_we_n, -- SDRAM write-enable
ba => pin_ba, -- SDRAM bank address
sAddr => pin_sAddr, -- SDRAM address
sData => pin_sData, -- SDRAM databus
dqmh => pin_dqmh, -- SDRAM DQMH
dqml => pin_dqml -- SDRAM DQML
);
-- synchronous reset. internal reset flag is set active by config. bitstream
-- and then gets reset after DLL clocks start.
process(sdram_bufclk)
begin
if (rising_edge(sdram_bufclk)) then
if sdram_lock='0' then
sysReset <= '1'; -- keep in reset until DLLs start up
else
--sysReset <= '0';
sysReset <= not pin_pushbtn; -- push button will reset
end if;
end if;
end process;
end arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -