📄 vga_ctrl.vhd
字号:
library IEEE;
use IEEE.std_logic_1164.all;
entity vga_ctrl is
port
(
clk: in std_logic; -- from bus
reset: in std_logic; -- from bus
chipselect: in std_logic; -- from bus
address: in std_logic_vector( 17 downto 0 ); -- from bus
read_n: in std_logic; -- from bus
write_n: in std_logic; -- from bus
writedata: in std_logic_vector( 15 downto 0 ); -- from bus
byteenable_n: in std_logic_vector( 1 downto 0 ); -- from bus
vd_inuse: in std_logic; -- from vga_display (async)
vd_scan: in std_logic; -- from vga_ctrl (async)
vd_addr: in std_logic_vector( 16 downto 0 ); -- from vga_display
vd_read_n: in std_logic; -- from vga_display
vd_be_n: in std_logic_vector( 1 downto 0 ); -- from vga_display
sram_dq: inout std_logic_vector( 15 downto 0 );
sram_addr: out std_logic_vector( 17 downto 0 ); -- export to sram
sram_we_n: out std_logic; -- export to sram
sram_oe_n: out std_logic; -- export to sram
sram_ub_n: out std_logic; -- export to sram
sram_lb_n: out std_logic; -- export to sram
sram_ce_n: out std_logic; -- export to sram
vd_ena: out std_logic; -- to vga_display
vd_data: out std_logic_vector( 15 downto 0 ); -- to vga_display
waitrequest: out std_logic; -- to bus
readdata: out std_logic_vector( 15 downto 0 ) -- to bus
);
end vga_ctrl;
architecture RTL of vga_ctrl is
type VC_STAT is ( VC_INIT, VC_IDLE, VC_WR_STATE, VC_RD_STATE, VC_WAIT_RW, VC_RW_DATA );
constant WRITABLE_BIT: integer := 0; -- I
constant DISP_EN_BIT: integer := 1; -- I/O
constant SWITCH_BIT: integer := 2; -- O
signal stat: VC_STAT;
signal stat_next: VC_STAT;
signal switch: std_logic; -- latch
signal switch_next: std_logic; -- latch
signal displsel: std_logic;
signal rwsel: std_logic;
signal disp_en: std_logic; -- latch
signal vd_inuse_r: std_logic;
signal vd_scan_r: std_logic;
signal unready: std_logic;
signal unready_dl: std_logic;
signal unready_dl2: std_logic;
begin
Reg_async: process( clk, vd_inuse, vd_scan )
begin
if( rising_edge( clk ) ) then
vd_inuse_r <= vd_inuse;
vd_scan_r <= vd_scan;
end if;
end process Reg_async;
sram_ce_n <= '0';
displsel <= switch;
rwsel <= not switch;
Stat_P: process( clk, reset, stat_next )
begin
if( rising_edge( clk ) ) then
if( reset = '1' ) then
stat <= VC_INIT;
else
stat <= stat_next;
end if;
end if;
end process Stat_P;
Stat_next_P: process( stat, chipselect, address, write_n, read_n, switch, switch_next )
begin
case stat is
when VC_INIT =>
stat_next <= VC_IDLE;
when VC_IDLE =>
stat_next <= VC_IDLE;
if( chipselect = '1' ) then
if( address(17) = '1' ) then
if( write_n = '0' ) then
stat_next <= VC_WR_STATE;
end if;
if( read_n = '0' ) then
stat_next <= VC_RD_STATE;
end if;
else
if( switch = switch_next ) then
stat_next <= VC_RW_DATA;
else
stat_next <= VC_WAIT_RW;
end if;
end if;
end if;
when VC_WR_STATE =>
if( chipselect = '0' ) then
stat_next <= VC_IDLE;
else
stat_next <= VC_WR_STATE;
end if;
when VC_RD_STATE =>
if( chipselect = '0' ) then
stat_next <= VC_IDLE;
else
stat_next <= VC_RD_STATE;
end if;
when VC_WAIT_RW =>
if( switch = switch_next ) then
stat_next <= VC_RW_DATA;
else
stat_next <= VC_WAIT_RW;
end if;
when VC_RW_DATA =>
if( chipselect = '0' ) then
stat_next <= VC_IDLE;
else
stat_next <= VC_RW_DATA;
end if;
when others =>
stat_next <= VC_INIT;
end case;
end process Stat_next_P;
Unready_P: process( stat, vd_inuse_r )
begin
case stat is
when VC_RW_DATA =>
unready <= vd_inuse_r;
when others =>
unready <= '1';
end case;
end process Unready_P;
Unready_delay: process( clk, unready, unready_dl )
begin
if( rising_edge( clk ) ) then
unready_dl2 <= unready_dl;
unready_dl <= unready;
end if;
end process Unready_delay;
Mux: process( clk, vd_scan_r, stat, unready, unready_dl, displsel, disp_en, vd_addr, vd_read_n, vd_be_n, sram_dq, chipselect, address, write_n, writedata, byteenable_n )
begin
if( rising_edge( clk ) ) then
if( vd_scan_r = '0' ) then
switch <= switch_next;
else
switch <= switch;
end if;
switch_next <= switch_next;
disp_en <= disp_en;
vd_ena <= disp_en;
vd_data <= sram_dq;
sram_dq <= ( others => 'Z' );
sram_addr <= displsel & vd_addr;
sram_we_n <= '1';
sram_oe_n <= vd_read_n;
sram_ub_n <= vd_be_n(1);
sram_lb_n <= vd_be_n(0);
waitrequest <= '1';
readdata <= ( others => '0' );
case stat is
when VC_INIT =>
switch <= '0';
switch_next <= '0';
disp_en <= '0';
when VC_IDLE =>
when VC_WR_STATE =>
waitrequest <= '0';
if( write_n = '0' ) then
disp_en <= writedata( DISP_EN_BIT );
if( writedata(SWITCH_BIT) = '1' ) then
switch <= switch;
switch_next <= not switch;
end if;
end if;
when VC_RD_STATE =>
waitrequest <= '0';
-- if( (vd_scan_r = '0') and (switch = switch_next) ) then
-- readdata( WRITABLE_BIT ) <= '1';
-- else
-- readdata( WRITABLE_BIT ) <= '0';
-- end if;
readdata( WRITABLE_BIT ) <= (not vd_scan_r) and (not (switch xor switch_next));
readdata( DISP_EN_BIT ) <= disp_en;
when VC_WAIT_RW =>
waitrequest <= '1';
switch <= switch_next;
when VC_RW_DATA =>
if( unready = '0' or unready_dl2 = '0' ) then
waitrequest <= unready or unready_dl2;
vd_data <= ( others => '0' );
sram_addr <= rwsel & address( 16 downto 0 );
if( write_n = '0' ) then
sram_dq <= writedata;
else
sram_dq <= ( others => 'Z' );
end if;
sram_we_n <= write_n;
sram_oe_n <= read_n;
sram_ub_n <= byteenable_n(1);
sram_lb_n <= byteenable_n(0);
readdata <= sram_dq;
end if;
when others =>
end case;
end if;
end process Mux;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -