Transcript WHYP

VGA-RAM
Discussion D10.5
3/27/2007-B
VGA - RAM
x
0
1
2
3
x
639
0
y
1
2
3
y
479
R G B
R G B
R G B
R G B
VGA - RAM
x
640
 160 words/row
4
0
1
2
x
3
639
0
y
1
2
3
160  480  76,800 words/screen
y
Address at (x,y)
x
addr  160 y 
4
479
Pixel
R G B
R G B
R G B
R G B
0
1
2
3
pixel  x mod 4
signal x,y: std_logic_vector(16 downto 0):
addr  160 y 
x
x
 (128  32) y 
4
4
y(9 downto 0) & “0000000”
pixel  x mod 4
y(11 downto 0) & “00000”
+
“00” & x(14 downto 0)
+
addr
pixel  x(1 downto 0)
Brian’s RAM Controller
Enable we
50 MHz
mclk
25 MHz
clk
Select
Device 0
Select
Device 1
Enable we
ram_ctrl
50 MHz
mclk
clk
25 MHz
clk
0
Select
Device 0
Dout0
1
Select
Device 1
ram_addr(18)
CE1
CE2
0
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
------
ram_ctrl
Ram_Ctrl.vhd
Created by Brian Carpenter 03 Dec 2005
This device will hook up to the memory and service
2 devices in 1 25Mhz clock cycle
Connect mclk to 50Mhz, clk to 25Mhz
-- NOTE: WE is active high
entity ram_ctrl is
Port (
mclk: in std_logic;
clk: in std_logic;
clr: in std_logic;
ram_ctrl
Addr0 : in std_logic_vector(18 downto 0);
Din0 : in std_logic_vector(15 downto 0);
Dout0 : out std_logic_vector(15 downto 0);
we0 : in std_logic;
Addr1 : in std_logic_vector(18 downto 0);
Din1 : in std_logic_vector(15 downto 0);
Dout1 : out std_logic_vector(15 downto 0);
we1 : in std_logic;
clk
0
Dout0
1
ram_addr(18)
CE1
CE2
0
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
A : out STD_LOGIC_VECTOR(17 downto 0);
IO10 : inout STD_LOGIC_VECTOR(15 downto 0);
IO11 : inout STD_LOGIC_VECTOR(15 downto 0);
CE1 : out STD_LOGIC;
UB1 : out STD_LOGIC;
LB1 : out STD_LOGIC;
0
CE2 : out STD_LOGIC;
UB2 : out STD_LOGIC;
1
ram_addr(18)
LB2 : out STD_LOGIC;
WE : out STD_LOGIC;
0
OE : out STD_LOGIC
);
1
Addr0
end ram_ctrl;
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
ram_ctrl
clk
Dout0
CE1
CE2
Dout1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
architecture ram_ctrl_arch of ram_ctrl is
ram_ctrl
signal ram_data : std_logic_vector(15 downto 0);
signal ram_addr : std_logic_vector(18 downto 0);
signal oe_out, we_out : std_logic;
begin
-- Combinational process to setup the outputs
comb: process(mclk,clk,Addr0,Din0,we0,Addr1,Din1,we1)
begin
-- Initialize signals to prevent unwanted latches
ram_data <= (others => '0');
ram_addr <= (others => '0');
oe_out <= '1';
we_out <= '1';
-- Switch between devices using the clk as a select line
if (clk = '1') then -- select device 0
ram_data <= Din0;
ram_addr <= Addr0;
ram_ctrl
oe_out <= we0;
else
-- select device 1
clk
ram_data <= Din1;
ram_addr <= Addr1;
0
oe_out <= we1;
Dout0
1
end if;
ram_addr(18)
CE1
CE2
0
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
-- enable the we only when mclk is low
if (mclk = '0') then -- enable the we
if (clk = '1') then -- select device 0
we_out <= not we0;
else
-- select device 1
we_out <= not we1;
end if;
0
end if;
1
end process comb;
ram_addr(18)
ram_ctrl
clk
Dout0
CE1
CE2
0
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
-- Latch the value for device 0, as it is handled first
seq: process(clk,clr,ram_addr,IO10,IO11)
begin
if (clr = '1') then
ram_ctrl
Dout0 <= (others => '0');
elsif (falling_edge(clk)) then
if ram_addr(18) = '0' then -- use IO10
clk
Dout0 <= IO10;
0
else
Dout0
1
Dout0 <= IO11;
ram_addr(18)
end if;
CE1
CE2
end if;
0
end process;
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
-- Don't latch device 1's output
Dout1 <= IO10 when ram_addr(18) = '0' else IO11;
ram_ctrl
-- Enable only 1 chip
CE1 <= ram_addr(18);
CE2 <= not ram_addr(18);
-- Determine which chips gets the data, use a tristate buffer
IO10 <= ram_data when oe_out = '1' else "ZZZZZZZZZZZZZZZZ";
IO11 <= ram_data when oe_out = '1' else "ZZZZZZZZZZZZZZZZ";
clk
0
Dout0
1
ram_addr(18)
CE1
CE2
0
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
-- Outputs that drive both chips
OE <= oe_out;
WE <= we_out;
A <= ram_addr(17 downto 0);
-- Constant outputs
UB1 <= '0';
LB1 <= '0';
UB2 <= '0';
LB2 <= '0';
ram_ctrl
clk
0
Dout0
1
ram_addr(18)
CE1
CE2
0
end ram_ctrl_arch;
Dout1
1
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
clk
1
0
1
we_out
mclk
WE
Refresh the video ram
clk
ram_ctrl
0
Dout0
1
ram_addr(18)
CE1
CE2
0
clk
clr
Addr0
Din0
we0
addr1
data1
vga_ram
Dout1
1
hsync
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
vsync
clk
1
0
1
we_out
mclk
red green blue
WE
data1(15:0)
from Dout1
vga_ram
d1ld
0
dreg1
dreg2
px1(15:0)
px2(15:0)
1
2
3
4
5
d2ld
6
7
pmsel(2:0)
pixel(3:0)
process(vidon, hc)
begin
0
red <= '0';
green <= '0';
blue <= '0';
if vidon = '1' then
red <= pixel(2);
green <= pixel(1);
blue <= pixel(0);
end if;
end process;
R
G
B
data1(15:0)
d1ld
0
vga_ctrl
dreg1
dreg2
px1(15:0)
px2(15:0)
1
2
3
4
5
d2ld
6
start
7
~vidon
pmsel(2:0)
s0
pmsel <= “000”
pmsel <= “111”
pixel(3:0)
vidon
s7
clk
pmsel <= “001”
ram_addr :=
s1
ram_addr + 1;
clr
pmsel <= “110”
pmsel <= “010”
s6
s2
d1ld <= '1';
addr1
data1
vga_ram
pmsel <= “101”
hsync
s5
vsync
s3
pmsel <= “011”
d2ld <= '1';
ram_addr :=
ram_addr + 1;
s4
red green blue
pmsel <= “100”
data1(15:0)
d1ld
0
dreg1
dreg2
px1(15:0)
px2(15:0)
1
2
3
4
5
d2ld
6
7
pmsel(2:0)
pixel(3:0)
dreg1 : reg
generic map(
N => 16
)
port map(
d => data1,
load => d1ld,
clr => clr,
clk => clk,
q => px1
);
dreg2 : reg
generic map(
N => 16
)
port map(
d => data1,
load => d2ld,
clr => clr,
clk => clk,
q => px2
);
data1(15:0)
d1ld
0
dreg1
dreg2
px1(15:0)
px2(15:0)
1
2
3
4
pixel(3:0)
5
mux1 : mux8g
generic map(
N => 4
)
port map(
a => px1(15 downto 12),
b => px1(11 downto 8),
c => px1(7 downto 4),
d => px1(3 downto 0),
e => px2(15 downto 12),
f => px2(11 downto 8),
g => px2(7 downto 4),
h => px2(3 downto 0),
sel => pmsel,
y => pixel
);
d2ld
6
7
pmsel(2:0)
U3 : vga_ctrl
port map(
clk => clk,
clr => clr,
vidon => vidon,
d1ld => d1ld,
d2ld => d2ld,
addr1 => addr1,
pmsel => pmsel
);
start
~vidon
s0
vidon
pmsel <= “000”
pmsel <= “111”
s7
pmsel <= “110”
pmsel <= “001”
ram_addr :=
s1
ram_addr + 1;
pmsel <= “010”
s6
s2
d1ld <= '1';
pmsel <= “101”
s5
s3
pmsel <= “011”
d2ld <= '1';
ram_addr :=
ram_addr + 1;
s4
pmsel <= “100”
ad1: process(clk, clr, present_state)
variable ram_addr: std_logic_vector(18 downto 0);
begin
if clr = '1' then
ram_addr := "0000000000000000000";
elsif clk'event and clk = '1' then
if present_state = s1 or present_state = s5 then
ram_addr := ram_addr + 1;
end if;
if ram_addr = ("001" & X"2C00") then
ram_addr := "0000000000000000000";
end if;
start
end if;
addr1 <= ram_addr;
s0
end process;
~vidon
vidon
pmsel <= “000”
pmsel <= “111”
s7
pmsel <= “110”
pmsel <= “001”
ram_addr :=
s1
ram_addr + 1;
pmsel <= “010”
s6
s2
d1ld <= '1';
pmsel <= “101”
s5
s3
pmsel <= “011”
d2ld <= '1';
ram_addr :=
ram_addr + 1;
s4
pmsel <= “100”
Clear Screen
clk
~goc
clr
wec := ‘0’
addrc :=
“000”&X”0000"
start
goc
addrc
goc
clrscn
datac := X”0000"
wec
donec := ‘0’
~goc
wec := ‘1’
clear
donec := ‘1’
addrc := addrc + 1
donec
wec := ‘0’
wtngo
addrc >= addr_size
goc
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clrscn is
Port ( clk : in std_logic;
clr : in std_logic;
go : in std_logic;
done : out std_logic;
wec : out std_logic;
addrc : out std_logic_vector(18 downto 0);
datac : out std_logic_vector(15 downto 0)
);
clk
clr
end clrscn;
addrc
goc
clrscn
datac := X”0000"
wec
donec
architecture clrscn of clrscn is
type state_type is (start, clear, wtngo);
signal state: state_type;
signal addr_count: STD_LOGIC_VECTOR (18 downto 0);
constant addr_size: STD_LOGIC_VECTOR (18 downto 0) :=
("001" & X"2C00"); --76,800
begin
datac <= X"0000";
~goc
addrc :=
“000”&X”0000"
wec := ‘0’
start
sreg: process(clk, clr)
~goc
begin
donec := ‘1’
if clr = '1' then
wec := ‘0’
wtngo
state <= start;
addr_count <= "0000000000000000000";
goc
wec <= '0';
done <= '1';
goc
donec := ‘0’
wec := ‘1’
clear
addrc := addrc + 1
addrc >= addr_size
elsif clk'event and clk = '1' then
case state is
when start =>
addr_count <= "0000000000000000000";
if go = '1' then
wec <= '1';
done <= '0';
state <= clear;
else
state <= start;
end if;
when clear =>
if addr_count >= addr_size then
addr_count <= "0000000000000000000";
state <= wtngo;
done <= '1';
wec <= '0';
else
addr_count <= addr_count + 1;
wec <= '1';
state <= clear;
-stay in clear
end if;
when wtngo =>
if go = '1' then
state <= wtngo;
else
state <= start;
end if;
end case;
~goc
end if;
end process;
addrc :=
start
“000”&X”0000"
wec := ‘0’
goc
addrc <= addr_count;
end clrscn;
donec := ‘0’
~goc
wec := ‘1’
clear
donec := ‘1’
wec := ‘0’
addrc := addrc + 1
wtngo
addrc >= addr_size
goc
Plot dot
x
y
clk clr
~go
color
gop
addrp
plot
datap
~go
go
start
wep
data_in
go
wtngo
addrout
write
read
addrp <= y*160 + x/4;
wep <= '0';
donep
datap <= data;
done <= '1';
wep <= '1';
setpix
Set color bits in data
data <= data_in;
wep <= '0';
x
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
y
clk clr
color
gop
addrp
plot
data_in
entity plot is
Port ( clk : in std_logic;
donep
clr : in std_logic;
go : in std_logic;
x, y : in std_logic_vector(9 downto 0);
data_in : in std_logic_vector(15 downto 0);
color : in std_logic_vector(2 downto 0);
done : out std_logic;
wep : out std_logic;
addrp : out std_logic_vector(18 downto 0);
datap : out std_logic_vector(15 downto 0)
);
end plot;
datap
wep
architecture plot of plot is
type state_type is (start, addrout, read, setpix, write, wtngo);
signal state: state_type;
signal ram_addr1, ram_addr2: STD_LOGIC_VECTOR (18 downto 0);
signal data: STD_LOGIC_VECTOR (15 downto 0);
signal px: STD_LOGIC_VECTOR (1 downto 0);
signal pixel: STD_LOGIC_VECTOR (3 downto 0);
constant addr_size: STD_LOGIC_VECTOR (18 downto 0) := ("001" & X"2C00");
--76,800
begin
pixel <= '0' & color;
process(x, y)
begin
ram_addr1
-ram_addr2
-px <= x(1
end process;
<= ("00" & y & "0000000") + ("0000" & y & "00000");
y*(128+32)
<= ram_addr1 + ("00000000000" & x(9 downto 2));
y*160+x/4
downto 0);
~go
~go
go
start
go
sreg: process(clk, clr)
begin
if clr = '1' then
datap <= data;
done <= '1';
state <= start;
wep <= '1';
addrp <= "0000000000000000000";
wep <= '0';
done <= ‘1';
elsif clk'event and clk = '1' then
case state is
when start =>
wep <= '0';
if go = '1' then
state <= addrout;
done <= ‘1';
else
state <= start;
end if;
wtngo
addrout
write
read
setpix
Set color bits in data
addrp <= y*160 + x/4;
wep <= '0';
data <= data_in;
wep <= '0';
~go
~go
when addrout =>
state <= read;
go
addrp <= ram_addr2;
wtngo
wep <= '0';
when read =>
state <= setpix;
data <= data_in;
wep <= '0';
datap <= data;
when setpix =>
write
done <= '1';
wep <= '1';
state <= write;
wep <= '0';
case px is
when "00" =>
data(15 downto 12) <= pixel;
when "01" =>
data(11 downto 8) <= pixel;
when "10" =>
data(7 downto 4) <= pixel;
when "11" =>
data(3 downto 0) <= pixel;
when others =>
null;
end case;
go
start
addrout
read
setpix
Set color bits in data
addrp <= y*160 + x/4;
wep <= '0';
data <= data_in;
wep <= '0';
when write =>
state <= wtngo;
datap <= data;
done <= '1';
wep <= '1';
when wtngo =>
wep <= '0';
if go = '1' then
state <= wtngo;
else
state <= start;
end if;
go
when others =>
null;
end case;
end if;
end process;
end plot;
datap <= data;
done <= '1';
wep <= '1';
~go
~go
go
start
wtngo
addrout
write
read
setpix
Set color bits in data
addrp <= y*160 + x/4;
wep <= '0';
data <= data_in;
wep <= '0';
x
y
clk clr
clk
addrp
color
0
1
gop
datap
plot
Addr0
0
data_in
Dout0
1
ram_addr(18)
CE1
wep
CE2
0
Dout1
1
1
donep
Din0
0
clk
clr
Addr0
Din0
we0
Addr1
Din1
we1
ram_addr(18:0)
1
A(17:0)
ram_data
IO10
oe_out
OE
0
IO11
addrc
goc
clrscn
1
datac := X”0000"
0
wec
donec
pcsel
clk
we0
1
0
1
we_out
mclk
WE