Rev 467 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4 | lvd | 1 | -- **** |
2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... |
||
3 | -- |
||
4 | -- |
||
5 | -- Ver 300 started tidyup |
||
6 | -- MikeJ March 2005 |
||
7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) |
||
8 | -- |
||
9 | -- **** |
||
10 | -- |
||
11 | -- Z80 compatible microprocessor core, asynchronous top level |
||
12 | -- |
||
13 | -- Version : 0247 |
||
14 | -- |
||
15 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) |
||
16 | -- |
||
17 | -- All rights reserved |
||
18 | -- |
||
19 | -- Redistribution and use in source and synthezised forms, with or without |
||
20 | -- modification, are permitted provided that the following conditions are met: |
||
21 | -- |
||
22 | -- Redistributions of source code must retain the above copyright notice, |
||
23 | -- this list of conditions and the following disclaimer. |
||
24 | -- |
||
25 | -- Redistributions in synthesized form must reproduce the above copyright |
||
26 | -- notice, this list of conditions and the following disclaimer in the |
||
27 | -- documentation and/or other materials provided with the distribution. |
||
28 | -- |
||
29 | -- Neither the name of the author nor the names of other contributors may |
||
30 | -- be used to endorse or promote products derived from this software without |
||
31 | -- specific prior written permission. |
||
32 | -- |
||
33 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||
34 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
||
35 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||
36 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
||
37 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
38 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
39 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
40 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
41 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
42 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
43 | -- POSSIBILITY OF SUCH DAMAGE. |
||
44 | -- |
||
45 | -- Please report bugs to the author, but before you do so, please |
||
46 | -- make sure that this is not a derivative work and that |
||
47 | -- you have the latest version of this file. |
||
48 | -- |
||
49 | -- The latest version of this file can be found at: |
||
50 | -- http://www.opencores.org/cvsweb.shtml/t80/ |
||
51 | -- |
||
52 | -- Limitations : |
||
53 | -- |
||
54 | -- File history : |
||
55 | -- |
||
56 | -- 0208 : First complete release |
||
57 | -- |
||
58 | -- 0211 : Fixed interrupt cycle |
||
59 | -- |
||
60 | -- 0235 : Updated for T80 interface change |
||
61 | -- |
||
62 | -- 0238 : Updated for T80 interface change |
||
63 | -- |
||
64 | -- 0240 : Updated for T80 interface change |
||
65 | -- |
||
66 | -- 0242 : Updated for T80 interface change |
||
67 | -- |
||
68 | -- 0247 : Fixed bus req/ack cycle |
||
69 | -- |
||
70 | |||
71 | library IEEE; |
||
72 | use IEEE.std_logic_1164.all; |
||
73 | use IEEE.numeric_std.all; |
||
74 | use work.T80_Pack.all; |
||
75 | |||
76 | entity T80a is |
||
77 | generic( |
||
78 | Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB |
||
79 | ); |
||
80 | port( |
||
81 | RESET_n : in std_logic; |
||
82 | CLK_n : in std_logic; |
||
83 | WAIT_n : in std_logic; |
||
84 | INT_n : in std_logic; |
||
85 | NMI_n : in std_logic; |
||
86 | BUSRQ_n : in std_logic; |
||
87 | M1_n : out std_logic; |
||
88 | MREQ_n : out std_logic; |
||
89 | IORQ_n : out std_logic; |
||
90 | RD_n : out std_logic; |
||
91 | WR_n : out std_logic; |
||
92 | RFSH_n : out std_logic; |
||
93 | HALT_n : out std_logic; |
||
94 | BUSAK_n : out std_logic; |
||
95 | A : out std_logic_vector(15 downto 0); |
||
467 | lvd | 96 | D : inout std_logic_vector(7 downto 0); |
97 | D_I : in std_logic_vector(7 downto 0); |
||
684 | lvd | 98 | D_O : out std_logic_vector(7 downto 0); |
99 | ResetPC : in std_logic_vector(15 downto 0); |
||
100 | ResetSP : in std_logic_vector(15 downto 0) |
||
467 | lvd | 101 | |
4 | lvd | 102 | ); |
103 | end T80a; |
||
104 | |||
105 | architecture rtl of T80a is |
||
106 | |||
107 | signal CEN : std_logic; |
||
108 | signal Reset_s : std_logic; |
||
109 | signal IntCycle_n : std_logic; |
||
110 | signal IORQ : std_logic; |
||
111 | signal NoRead : std_logic; |
||
112 | signal Write : std_logic; |
||
113 | signal MREQ : std_logic; |
||
114 | signal MReq_Inhibit : std_logic; |
||
115 | signal Req_Inhibit : std_logic; |
||
116 | signal RD : std_logic; |
||
117 | signal MREQ_n_i : std_logic; |
||
118 | signal IORQ_n_i : std_logic; |
||
119 | signal RD_n_i : std_logic; |
||
120 | signal WR_n_i : std_logic; |
||
121 | signal RFSH_n_i : std_logic; |
||
122 | signal BUSAK_n_i : std_logic; |
||
123 | signal A_i : std_logic_vector(15 downto 0); |
||
124 | signal DO : std_logic_vector(7 downto 0); |
||
125 | signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser |
||
126 | signal Wait_s : std_logic; |
||
127 | signal MCycle : std_logic_vector(2 downto 0); |
||
128 | signal TState : std_logic_vector(2 downto 0); |
||
129 | |||
130 | begin |
||
131 | |||
132 | CEN <= '1'; |
||
133 | |||
134 | BUSAK_n <= BUSAK_n_i; |
||
135 | MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); |
||
136 | RD_n_i <= not RD or Req_Inhibit; |
||
137 | |||
138 | MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; |
||
139 | IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; |
||
140 | RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; |
||
141 | WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; |
||
142 | RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; |
||
143 | A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); |
||
144 | D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); |
||
145 | |||
467 | lvd | 146 | D_O <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); |
147 | |||
148 | |||
4 | lvd | 149 | process (RESET_n, CLK_n) |
150 | begin |
||
151 | if RESET_n = '0' then |
||
152 | Reset_s <= '0'; |
||
153 | elsif CLK_n'event and CLK_n = '1' then |
||
154 | Reset_s <= '1'; |
||
155 | end if; |
||
156 | end process; |
||
157 | |||
158 | u0 : T80 |
||
159 | generic map( |
||
160 | Mode => Mode, |
||
161 | IOWait => 1) |
||
162 | port map( |
||
163 | CEN => CEN, |
||
164 | M1_n => M1_n, |
||
165 | IORQ => IORQ, |
||
166 | NoRead => NoRead, |
||
167 | Write => Write, |
||
168 | RFSH_n => RFSH_n_i, |
||
169 | HALT_n => HALT_n, |
||
170 | WAIT_n => Wait_s, |
||
171 | INT_n => INT_n, |
||
172 | NMI_n => NMI_n, |
||
173 | RESET_n => Reset_s, |
||
684 | lvd | 174 | BUSRQ_n => BUSRQ_n, BUSAK_n => BUSAK_n_i, |
4 | lvd | 175 | CLK_n => CLK_n, |
176 | A => A_i, |
||
467 | lvd | 177 | DInst => D_I, -- D -> D_I |
4 | lvd | 178 | DI => DI_Reg, |
179 | DO => DO, |
||
180 | MC => MCycle, |
||
181 | TS => TState, |
||
684 | lvd | 182 | IntCycle_n => IntCycle_n, |
183 | ResetPC => ResetPC, |
||
184 | ResetSP => ResetSP |
||
185 | ); |
||
4 | lvd | 186 | |
187 | process (CLK_n) |
||
188 | begin |
||
189 | if CLK_n'event and CLK_n = '0' then |
||
190 | Wait_s <= WAIT_n; |
||
191 | if TState = "011" and BUSAK_n_i = '1' then |
||
467 | lvd | 192 | DI_Reg <= to_x01(D_I); -- D -> D_I |
4 | lvd | 193 | end if; |
194 | end if; |
||
195 | end process; |
||
196 | |||
197 | process (Reset_s,CLK_n) |
||
198 | begin |
||
199 | if Reset_s = '0' then |
||
200 | WR_n_i <= '1'; |
||
201 | elsif CLK_n'event and CLK_n = '1' then |
||
202 | WR_n_i <= '1'; |
||
203 | if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! |
||
204 | WR_n_i <= not Write; |
||
205 | end if; |
||
206 | end if; |
||
207 | end process; |
||
208 | |||
209 | process (Reset_s,CLK_n) |
||
210 | begin |
||
211 | if Reset_s = '0' then |
||
212 | Req_Inhibit <= '0'; |
||
213 | elsif CLK_n'event and CLK_n = '1' then |
||
214 | if MCycle = "001" and TState = "010" then |
||
215 | Req_Inhibit <= '1'; |
||
216 | else |
||
217 | Req_Inhibit <= '0'; |
||
218 | end if; |
||
219 | end if; |
||
220 | end process; |
||
221 | |||
222 | process (Reset_s,CLK_n) |
||
223 | begin |
||
224 | if Reset_s = '0' then |
||
225 | MReq_Inhibit <= '0'; |
||
226 | elsif CLK_n'event and CLK_n = '0' then |
||
227 | if MCycle = "001" and TState = "010" then |
||
228 | MReq_Inhibit <= '1'; |
||
229 | else |
||
230 | MReq_Inhibit <= '0'; |
||
231 | end if; |
||
232 | end if; |
||
233 | end process; |
||
234 | |||
235 | process(Reset_s,CLK_n) |
||
236 | begin |
||
237 | if Reset_s = '0' then |
||
238 | RD <= '0'; |
||
239 | IORQ_n_i <= '1'; |
||
240 | MREQ <= '0'; |
||
241 | elsif CLK_n'event and CLK_n = '0' then |
||
242 | |||
243 | if MCycle = "001" then |
||
244 | if TState = "001" then |
||
245 | RD <= IntCycle_n; |
||
246 | MREQ <= IntCycle_n; |
||
247 | IORQ_n_i <= IntCycle_n; |
||
248 | end if; |
||
249 | if TState = "011" then |
||
250 | RD <= '0'; |
||
251 | IORQ_n_i <= '1'; |
||
252 | MREQ <= '1'; |
||
253 | end if; |
||
254 | if TState = "100" then |
||
255 | MREQ <= '0'; |
||
256 | end if; |
||
257 | else |
||
258 | if TState = "001" and NoRead = '0' then |
||
259 | RD <= not Write; |
||
260 | IORQ_n_i <= not IORQ; |
||
261 | MREQ <= not IORQ; |
||
262 | end if; |
||
263 | if TState = "011" then |
||
264 | RD <= '0'; |
||
265 | IORQ_n_i <= '1'; |
||
266 | MREQ <= '0'; |
||
267 | end if; |
||
268 | end if; |
||
269 | end if; |
||
270 | end process; |
||
271 | |||
272 | end; |