1 |
16 |
rudi |
--
|
2 |
|
|
-- file: wb_slave.vhd
|
3 |
|
|
-- project: VGA/LCD controller
|
4 |
|
|
-- author: Richard Herveille
|
5 |
|
|
-- rev 1.0 May 10th, 2001
|
6 |
|
|
-- rev 1.1 June 3rd, 2001. Changed WISHBONE ADR_I. Addresses are defined as byte-oriented, instead of databus independent.
|
7 |
|
|
-- rev 1.2 July 15th, 2001. Added CLUT bank switching.
|
8 |
|
|
|
9 |
|
|
library ieee;
|
10 |
|
|
use ieee.std_logic_1164.all;
|
11 |
|
|
use ieee.std_logic_arith.all;
|
12 |
|
|
|
13 |
|
|
entity wb_slave is
|
14 |
|
|
port (
|
15 |
|
|
CLK_I : in std_logic;
|
16 |
|
|
RST_I : in std_logic;
|
17 |
|
|
NRESET : in std_logic;
|
18 |
|
|
ADR_I : in unsigned(4 downto 2);
|
19 |
|
|
DAT_I : in std_logic_vector(31 downto 0);
|
20 |
|
|
DAT_O : out std_logic_vector(31 downto 0);
|
21 |
|
|
SEL_I : in std_logic_vector(3 downto 0);
|
22 |
|
|
WE_I : in std_logic;
|
23 |
|
|
STB_I : in std_logic;
|
24 |
|
|
CYC_I : in std_logic;
|
25 |
|
|
ACK_O : out std_logic;
|
26 |
|
|
ERR_O : out std_logic;
|
27 |
|
|
INTA_O : out std_logic;
|
28 |
|
|
|
29 |
|
|
-- control register settings
|
30 |
|
|
BL : out std_logic; -- blanking level
|
31 |
|
|
CSL : out std_logic; -- composite sync level
|
32 |
|
|
VSL : out std_logic; -- vsync level
|
33 |
|
|
HSL : out std_logic; -- hsync level
|
34 |
|
|
PC : out std_logic; -- pseudo color
|
35 |
|
|
CD : out std_logic_vector(1 downto 0); -- color depth
|
36 |
|
|
VBL : out std_logic_vector(1 downto 0); -- burst length
|
37 |
|
|
CBSW : out std_logic; -- clut bank switching enable
|
38 |
|
|
VBSW : out std_logic; -- video page bank switching enable
|
39 |
|
|
Ven : out std_logic; -- video system enable
|
40 |
|
|
|
41 |
|
|
-- status register inputs
|
42 |
|
|
AVMP, -- active video memory page
|
43 |
|
|
ACMP : in std_logic; -- active clut page
|
44 |
|
|
bsint_in,
|
45 |
|
|
hint_in,
|
46 |
|
|
vint_in,
|
47 |
|
|
luint_in,
|
48 |
|
|
sint_in : in std_logic; -- interrupt request signals
|
49 |
|
|
|
50 |
|
|
-- Horizontal Timing Register
|
51 |
|
|
Thsync : out unsigned(7 downto 0);
|
52 |
|
|
Thgdel : out unsigned(7 downto 0);
|
53 |
|
|
Thgate : out unsigned(15 downto 0);
|
54 |
|
|
Thlen : out unsigned(15 downto 0);
|
55 |
|
|
|
56 |
|
|
-- Vertical Timing Register
|
57 |
|
|
Tvsync : out unsigned(7 downto 0);
|
58 |
|
|
Tvgdel : out unsigned(7 downto 0);
|
59 |
|
|
Tvgate : out unsigned(15 downto 0);
|
60 |
|
|
Tvlen : out unsigned(15 downto 0);
|
61 |
|
|
|
62 |
|
|
VBARa,
|
63 |
|
|
VBARb : buffer unsigned(31 downto 2);
|
64 |
|
|
CBAR : buffer unsigned(31 downto 11)
|
65 |
|
|
);
|
66 |
|
|
end entity wb_slave;
|
67 |
|
|
|
68 |
|
|
architecture structural of wb_slave is
|
69 |
|
|
signal ctrl, stat, htim, vtim, hvlen : std_logic_vector(31 downto 0);
|
70 |
|
|
signal HINT, VINT, BSINT, LUINT, SINT : std_logic;
|
71 |
|
|
signal HIE, VIE, BSIE : std_logic;
|
72 |
|
|
signal acc, acc32, reg_acc : std_logic;
|
73 |
|
|
begin
|
74 |
|
|
acc <= CYC_I and STB_I;
|
75 |
|
|
acc32 <= SEL_I(3) and SEL_I(2) and SEL_I(1) and SEL_I(0);
|
76 |
|
|
reg_acc <= acc and acc32 and WE_I;
|
77 |
|
|
ACK_O <= acc and acc32;
|
78 |
|
|
ERR_O <= acc and not acc32;
|
79 |
|
|
|
80 |
|
|
gen_regs: process(CLK_I, nRESET)
|
81 |
|
|
begin
|
82 |
|
|
if (nReset = '0') then
|
83 |
|
|
ctrl <= (others => '0');
|
84 |
|
|
htim <= (others => '0');
|
85 |
|
|
vtim <= (others => '0');
|
86 |
|
|
hvlen <= (others => '0');
|
87 |
|
|
VBARa <= (others => '0');
|
88 |
|
|
VBARb <= (others => '0');
|
89 |
|
|
CBAR <= (others => '0');
|
90 |
|
|
elsif(CLK_I'event and CLK_I = '1') then
|
91 |
|
|
if (RST_I = '1') then
|
92 |
|
|
ctrl <= (others => '0');
|
93 |
|
|
htim <= (others => '0');
|
94 |
|
|
vtim <= (others => '0');
|
95 |
|
|
hvlen <= (others => '0');
|
96 |
|
|
VBARa <= (others => '0');
|
97 |
|
|
VBARb <= (others => '0');
|
98 |
|
|
CBAR <= (others => '0');
|
99 |
|
|
elsif (reg_acc = '1') then
|
100 |
|
|
case ADR_I is
|
101 |
|
|
when "000" => ctrl <= DAT_I;
|
102 |
|
|
when "001" => null; -- status register (see gen_stat process)
|
103 |
|
|
when "010" => htim <= DAT_I;
|
104 |
|
|
when "011" => vtim <= DAT_I;
|
105 |
|
|
when "100" => hvlen <= DAT_I;
|
106 |
|
|
when "101" => VBARa <= unsigned(DAT_I(31 downto 2));
|
107 |
|
|
when "110" => VBARb <= unsigned(DAT_I(31 downto 2));
|
108 |
|
|
when "111" => CBAR <= unsigned(DAT_I(31 downto 11));
|
109 |
|
|
|
110 |
|
|
when others => null; -- should never happen
|
111 |
|
|
end case;
|
112 |
|
|
end if;
|
113 |
|
|
end if;
|
114 |
|
|
end process gen_regs;
|
115 |
|
|
|
116 |
|
|
-- generate status register
|
117 |
|
|
gen_stat: process(CLK_I, nRESET)
|
118 |
|
|
begin
|
119 |
|
|
if (nReset = '0') then
|
120 |
|
|
stat <= (others => '0');
|
121 |
|
|
elsif(CLK_I'event and CLK_I = '1') then
|
122 |
|
|
if (RST_I = '1') then
|
123 |
|
|
stat <= (others => '0');
|
124 |
|
|
else
|
125 |
|
|
stat(17) <= ACMP;
|
126 |
|
|
stat(16) <= AVMP;
|
127 |
|
|
stat( 6) <= bsint_in or (stat(6) and not (reg_acc and WE_I and DAT_I(6)) );
|
128 |
|
|
stat( 5) <= hint_in or (stat(5) and not (reg_acc and WE_I and DAT_I(5)) );
|
129 |
|
|
stat( 4) <= vint_in or (stat(4) and not (reg_acc and WE_I and DAT_I(4)) );
|
130 |
|
|
stat( 1) <= luint_in or (stat(1) and not (reg_acc and WE_I and DAT_I(1)) );
|
131 |
|
|
stat( 0) <= sint_in or (stat(0) and not (reg_acc and WE_I and DAT_I(0)) );
|
132 |
|
|
end if;
|
133 |
|
|
end if;
|
134 |
|
|
end process gen_stat;
|
135 |
|
|
|
136 |
|
|
-- decode control register
|
137 |
|
|
BL <= ctrl(15);
|
138 |
|
|
CSL <= ctrl(14);
|
139 |
|
|
VSL <= ctrl(13);
|
140 |
|
|
HSL <= ctrl(12);
|
141 |
|
|
PC <= ctrl(11);
|
142 |
|
|
CD <= ctrl(10 downto 9);
|
143 |
|
|
VBL <= ctrl(8 downto 7);
|
144 |
|
|
CBSW <= ctrl(5);
|
145 |
|
|
VBSW <= ctrl(4);
|
146 |
|
|
BSIE <= ctrl(3);
|
147 |
|
|
HIE <= ctrl(2);
|
148 |
|
|
VIE <= ctrl(1);
|
149 |
|
|
Ven <= ctrl(0);
|
150 |
|
|
|
151 |
|
|
-- decode status register
|
152 |
|
|
BSINT <= stat(6);
|
153 |
|
|
HINT <= stat(5);
|
154 |
|
|
VINT <= stat(4);
|
155 |
|
|
LUINT <= stat(1);
|
156 |
|
|
SINT <= stat(0);
|
157 |
|
|
|
158 |
|
|
-- decode Horizontal Timing Register
|
159 |
|
|
Thsync <= unsigned(htim(31 downto 24));
|
160 |
|
|
Thgdel <= unsigned(htim(23 downto 16));
|
161 |
|
|
Thgate <= unsigned(htim(15 downto 0));
|
162 |
|
|
Thlen <= unsigned(hvlen(31 downto 16));
|
163 |
|
|
|
164 |
|
|
-- decode Vertical Timing Register
|
165 |
|
|
Tvsync <= unsigned(vtim(31 downto 24));
|
166 |
|
|
Tvgdel <= unsigned(vtim(23 downto 16));
|
167 |
|
|
Tvgate <= unsigned(vtim(15 downto 0));
|
168 |
|
|
Tvlen <= unsigned(hvlen(15 downto 0));
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
-- assign output
|
172 |
|
|
with ADR_I select
|
173 |
|
|
DAT_O <= ctrl when "000",
|
174 |
|
|
stat when "001",
|
175 |
|
|
htim when "010",
|
176 |
|
|
vtim when "011",
|
177 |
|
|
hvlen when "100",
|
178 |
|
|
std_logic_vector(VBARa & "00") when "101",
|
179 |
|
|
std_logic_vector(VBARb & "00") when "110",
|
180 |
|
|
std_logic_vector(CBAR & ACMP & "0000000000") when others;
|
181 |
|
|
|
182 |
|
|
-- generate interrupt request signal
|
183 |
|
|
INTA_O <= (HINT and HIE) or (VINT and VIE) or (BSINT and BSIE) or LUINT or SINT;
|
184 |
|
|
end architecture structural;
|
185 |
|
|
|