w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
ibdr_pc11.vhd
Go to the documentation of this file.
1-- $Id: ibdr_pc11.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2009-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: ibdr_pc11 - syn
7-- Description: ibus dev(rem): PC11
8--
9-- Dependencies: -
10-- Test bench: xxdp: zpcae0
11-- Target Devices: generic
12-- Tool versions: ise 8.2-14.7; viv 2014.4-2017.2; ghdl 0.18-0.35
13--
14-- Synthesized (xst):
15-- Date Rev ise Target flop lutl lutm slic t peri
16-- 2010-10-17 333 12.1 M53d xc3s1000-4 26 97 0 57 s 6.0
17-- 2009-06-28 230 10.1.03 K39 xc3s1000-4 25 92 0 54 s 4.9
18--
19-- Revision History:
20-- Date Rev Version Comment
21-- 2019-04-27 1140 1.4.2 set rbuf.[rp]size0
22-- 2019-04-24 1137 1.4.1 add rcsr.ir,ique,iack and pcsr.ir fields (rem)
23-- 2019-04-06 1126 1.4 for pc11_buf compat: pbuf.pval in bit 15 and 8;
24-- move rbusy reporting from pbuf to rbuf register
25-- 2013-05-04 515 1.3 BUGFIX: r.rbuf was immediately cleared ! Was broken
26-- since ibus V2 update, never tested afterwards...
27-- 2011-11-18 427 1.2.2 now numeric_std clean
28-- 2010-10-23 335 1.2.1 rename RRI_LAM->RB_LAM;
29-- 2010-10-17 333 1.2 use ibus V2 interface
30-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ
31-- 2009-06-28 230 1.0 prdy now inits to '1'; setting err bit in csr now
32-- causes interrupt, if enabled; validated with zpcae0
33-- 2009-06-01 221 0.9 Initial version (untested)
34------------------------------------------------------------------------------
35
36library ieee;
37use ieee.std_logic_1164.all;
38use ieee.numeric_std.all;
39
40use work.slvtypes.all;
41use work.iblib.all;
42
43-- ----------------------------------------------------------------------------
44entity ibdr_pc11 is -- ibus dev(rem): PC11
45 -- fixed address: 177550
46 port (
47 CLK : in slbit; -- clock
48 RESET : in slbit; -- system reset
49 BRESET : in slbit; -- ibus reset
50 RB_LAM : out slbit; -- remote attention
51 IB_MREQ : in ib_mreq_type; -- ibus request
52 IB_SRES : out ib_sres_type; -- ibus response
53 EI_REQ_PTR : out slbit; -- interrupt request, reader
54 EI_REQ_PTP : out slbit; -- interrupt request, punch
55 EI_ACK_PTR : in slbit; -- interrupt acknowledge, reader
56 EI_ACK_PTP : in slbit -- interrupt acknowledge, punch
57 );
58end ibdr_pc11;
59
60architecture syn of ibdr_pc11 is
61
62 constant ibaddr_pc11 : slv16 := slv(to_unsigned(8#177550#,16));
63
64 constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset
65 constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset
66 constant ibaddr_pcsr : slv2 := "10"; -- pcsr address offset
67 constant ibaddr_pbuf : slv2 := "11"; -- pbuf address offset
68
69 constant rcsr_ibf_rerr : integer := 15;
70 constant rcsr_ibf_rbusy : integer := 11;
71 constant rcsr_ibf_rdone : integer := 7;
72 constant rcsr_ibf_rie : integer := 6;
73 constant rcsr_ibf_rir : integer := 5;
74 constant rcsr_ibf_ique : integer := 3;
75 constant rcsr_ibf_iack : integer := 2;
76 constant rcsr_ibf_renb : integer := 0;
77
78 constant rbuf_ibf_rbusy : integer := 15;
79 constant rbuf_ibf_rsize0: integer := 8;
80 constant rbuf_ibf_psize0: integer := 0;
81 subtype rbuf_ibf_data is integer range 7 downto 0;
82
83 constant pcsr_ibf_perr : integer := 15;
84 constant pcsr_ibf_prdy : integer := 7;
85 constant pcsr_ibf_pie : integer := 6;
86 constant pcsr_ibf_pir : integer := 5;
87
88 constant pbuf_ibf_pval : integer := 15;
89 constant pbuf_ibf_pval8 : integer := 8;
90
91 type regs_type is record -- state registers
92 ibsel : slbit; -- ibus select
93 rerr : slbit; -- rcsr: reader error
94 rbusy : slbit; -- rcsr: reader busy
95 rdone : slbit; -- rcsr: reader done
96 rie : slbit; -- rcsr: reader interrupt enable
97 rbuf : slv8; -- rbuf:
98 rintreq : slbit; -- ptr interrupt request
99 rique : slbit; -- ptr interrupt queued (req set)
100 riack : slbit; -- ptr interrupt acknowledged
101 perr : slbit; -- pcsr: punch error
102 prdy : slbit; -- pcsr: punch ready
103 pie : slbit; -- pcsr: punch interrupt enable
104 pbuf : slv8; -- pbuf:
105 pintreq : slbit; -- ptp interrupt request
106 end record regs_type;
107
108 constant regs_init : regs_type := (
109 '0', -- ibsel
110 '1', -- rerr (init=1!)
111 '0','0','0', -- rbusy,rdone,rie
112 (others=>'0'), -- rbuf
113 '0','0','0', -- rintreq,rique,riack
114 '1', -- perr (init=1!)
115 '1', -- prdy (init=1!)
116 '0', -- pie
117 (others=>'0'), -- pbuf
118 '0' -- pintreq
119 );
120
123
124begin
125
126 proc_regs: process (CLK)
127 begin
128 if rising_edge(CLK) then
129 if BRESET = '1' then -- BRESET is 1 for system and ibus reset
130 R_REGS <= regs_init; --
131 if RESET = '0' then -- if RESET=0 we do just an ibus reset
132 R_REGS.rerr <= N_REGS.rerr; -- don't reset RERR flag
133 R_REGS.perr <= N_REGS.perr; -- don't reset PERR flag
134 end if;
135 else
136 R_REGS <= N_REGS;
137 end if;
138 end if;
139 end process proc_regs;
140
141 proc_next : process (R_REGS, IB_MREQ, EI_ACK_PTR, EI_ACK_PTP)
142 variable r : regs_type := regs_init;
143 variable n : regs_type := regs_init;
144 variable idout : slv16 := (others=>'0');
145 variable ibreq : slbit := '0';
146 variable ibrd : slbit := '0';
147 variable ibw0 : slbit := '0';
148 variable ibw1 : slbit := '0';
149 variable ilam : slbit := '0';
150 begin
151
152 r := R_REGS;
153 n := R_REGS;
154
155 idout := (others=>'0');
156 ibreq := IB_MREQ.re or IB_MREQ.we;
157 ibrd := IB_MREQ.re;
158 ibw0 := IB_MREQ.we and IB_MREQ.be0;
159 ibw1 := IB_MREQ.we and IB_MREQ.be1;
160 ilam := '0';
161
162 -- ibus address decoder
163 n.ibsel := '0';
164 if IB_MREQ.aval='1' and
165 IB_MREQ.addr(12 downto 3)=ibaddr_pc11(12 downto 3) then
166 n.ibsel := '1';
167 end if;
168
169 -- ibus transactions
170 if r.ibsel = '1' then
171 case IB_MREQ.addr(2 downto 1) is
172
173 when ibaddr_rcsr => -- RCSR -- reader control status -----
174
175 idout(rcsr_ibf_rerr) := r.rerr;
176 idout(rcsr_ibf_rbusy) := r.rbusy;
177 idout(rcsr_ibf_rdone) := r.rdone;
178 idout(rcsr_ibf_rie) := r.rie;
179
180 if IB_MREQ.racc = '0' then -- cpu ---------------------
181 if ibw0 = '1' then
182 n.rie := IB_MREQ.din(rcsr_ibf_rie);
183 if IB_MREQ.din(rcsr_ibf_rie) = '1' then-- set IE to 1
184 if r.rie = '0' and -- IE 0->1 transition
185 IB_MREQ.din(rcsr_ibf_renb)='0' and -- when RENB not set
186 (r.rerr='1' or r.rdone='1') then -- but err or done set
187 n.rintreq := '1'; -- request interrupt
188 n.rique := '1'; -- and set que flag
189 end if;
190 else -- set IE to 0
191 n.rintreq := '0'; -- cancel interrupts
192 end if;
193 if IB_MREQ.din(rcsr_ibf_renb) = '1' then -- set RENB
194 if r.rerr = '0' then -- if not in error state
195 n.rbusy := '1'; -- set busy
196 n.rdone := '0'; -- clear done
197 n.rbuf := (others=>'0'); -- clear buffer
198 n.rintreq := '0'; -- cancel interrupt
199 n.rique := '0'; -- and que flag
200 n.riack := '0'; -- and ack flag
201 ilam := '1'; -- rri lam
202 else -- if in error state
203 if r.rie = '1' then -- if interrupts on
204 n.rintreq := '1'; -- request interrupt
205 n.rique := '1'; -- and set que flag
206 end if;
207 end if;
208 end if;
209 end if;
210
211 else -- rri ---------------------
212 idout(rcsr_ibf_rir) := r.rintreq;
213 idout(rcsr_ibf_ique) := r.rique;
214 idout(rcsr_ibf_iack) := r.riack;
215
216 if ibw1 = '1' then
217 n.rerr := IB_MREQ.din(rcsr_ibf_rerr); -- set ERR bit
218 if IB_MREQ.din(rcsr_ibf_rerr)='1' -- if 0->1 transition
219 and r.rerr='0' then
220 n.rbusy := '0'; -- clear busy
221 n.rdone := '0'; -- clear done
222 if r.rie = '1' then -- if interrupts on
223 n.rintreq := '1'; -- request interrupt
224 n.rique := '1'; -- and set que flag
225 end if;
226 end if;
227 end if;
228 end if;
229
230 when ibaddr_rbuf => -- RBUF -- reader data buffer --------
231
232 if IB_MREQ.racc = '0' then -- cpu ---------------------
233 idout(rbuf_ibf_data) := r.rbuf;
234 if ibreq = '1' then -- !! PC11 is unusual !!
235 n.rdone := '0'; -- *any* read or write will clear done
236 n.rbuf := (others=>'0'); -- and the reader buffer
237 n.rintreq := '0'; -- also interrupt is canceled
238 end if;
239
240 else -- rri ---------------------
241 idout(rbuf_ibf_rbusy) := r.rbusy;
242 idout(rbuf_ibf_rsize0) := r.rdone; -- rbuf occupied when rdone=1
243 idout(rbuf_ibf_psize0) := not r.prdy; -- pbuf empty when prdy=1
244 if ibw0 = '1' then
245 n.rbuf := IB_MREQ.din(rbuf_ibf_data);
246 n.rbusy := '0';
247 n.rdone := '1';
248 if r.rie = '1' then -- if interrupts on
249 n.rintreq := '1'; -- request interrupt
250 n.rique := '1'; -- and set que flag
251 end if;
252 end if;
253 end if;
254
255 when ibaddr_pcsr => -- PCSR -- punch control status ------
256
257 idout(pcsr_ibf_perr) := r.perr;
258 idout(pcsr_ibf_prdy) := r.prdy;
259 idout(pcsr_ibf_pie) := r.pie;
260
261 if IB_MREQ.racc = '0' then -- cpu ---------------------
262 if ibw0 = '1' then
263 n.pie := IB_MREQ.din(pcsr_ibf_pie);
264 if IB_MREQ.din(pcsr_ibf_pie) = '1' then-- set IE to 1
265 if r.pie='0' and -- IE 0->1 transition
266 (r.perr='1' or r.prdy='1') then -- but err or done set
267 n.pintreq := '1'; -- request interrupt
268 end if;
269 else -- set IE to 0
270 n.pintreq := '0'; -- cancel interrupts
271 end if;
272 end if;
273
274 else -- rri ---------------------
275 idout(pcsr_ibf_pir) := r.pintreq;
276 if ibw1 = '1' then
277 n.perr := IB_MREQ.din(pcsr_ibf_perr); -- set ERR bit
278 if IB_MREQ.din(pcsr_ibf_perr)='1' -- if 0->1 transition
279 and r.perr='0' then
280 n.prdy := '1'; -- set ready
281 if r.pie = '1' then -- if interrupts on
282 n.pintreq := '1'; -- request interrupt
283 end if;
284 end if;
285 end if;
286 end if;
287
288 when ibaddr_pbuf => -- PBUF -- punch data buffer ---------
289
290 if IB_MREQ.racc = '0' then -- cpu ---------------------
291 if ibw0 = '1' then
292 if r.perr = '0' then -- if not in error state
293 n.pbuf := IB_MREQ.din(n.pbuf'range);
294 n.prdy := '0'; -- clear ready
295 n.pintreq := '0'; -- cancel interrupts
296 ilam := '1'; -- rri lam
297 else -- if in error state
298 if r.pie = '1' then -- if interrupts on
299 n.pintreq := '1'; -- request interrupt
300 end if;
301 end if;
302 end if;
303
304 else -- rri ---------------------
305 idout(r.pbuf'range) := r.pbuf;
306 idout(pbuf_ibf_pval) := not r.prdy;
307 idout(pbuf_ibf_pval8) := not r.prdy;
308 if ibrd = '1' then
309 n.prdy := '1';
310 if r.pie = '1' then
311 n.pintreq := '1';
312 end if;
313 end if;
314 end if;
315
316 when others => null;
317 end case;
318
319 end if;
320
321 -- other state changes
322 if EI_ACK_PTR = '1' then
323 n.rintreq := '0';
324 n.riack := '1';
325 end if;
326 if EI_ACK_PTP = '1' then
327 n.pintreq := '0';
328 end if;
329
330 N_REGS <= n;
331
332 IB_SRES.dout <= idout;
333 IB_SRES.ack <= r.ibsel and ibreq;
334 IB_SRES.busy <= '0';
335
336 RB_LAM <= ilam;
337 EI_REQ_PTR <= r.rintreq;
338 EI_REQ_PTP <= r.pintreq;
339
340 end process proc_next;
341
342
343end syn;
integer := 0 rbuf_ibf_psize0
Definition: ibdr_pc11.vhd:80
slv2 := "01" ibaddr_rbuf
Definition: ibdr_pc11.vhd:65
integer := 15 pbuf_ibf_pval
Definition: ibdr_pc11.vhd:88
integer := 15 rcsr_ibf_rerr
Definition: ibdr_pc11.vhd:69
integer := 0 rcsr_ibf_renb
Definition: ibdr_pc11.vhd:76
slv2 := "00" ibaddr_rcsr
Definition: ibdr_pc11.vhd:64
regs_type := regs_init N_REGS
Definition: ibdr_pc11.vhd:122
integer := 5 rcsr_ibf_rir
Definition: ibdr_pc11.vhd:73
integer := 3 rcsr_ibf_ique
Definition: ibdr_pc11.vhd:74
integer := 2 rcsr_ibf_iack
Definition: ibdr_pc11.vhd:75
integer := 15 pcsr_ibf_perr
Definition: ibdr_pc11.vhd:83
slv16 := slv( to_unsigned( 8#177550#, 16) ) ibaddr_pc11
Definition: ibdr_pc11.vhd:62
integer := 5 pcsr_ibf_pir
Definition: ibdr_pc11.vhd:86
integer range 7 downto 0 rbuf_ibf_data
Definition: ibdr_pc11.vhd:81
integer := 8 rbuf_ibf_rsize0
Definition: ibdr_pc11.vhd:79
integer := 11 rcsr_ibf_rbusy
Definition: ibdr_pc11.vhd:70
integer := 7 rcsr_ibf_rdone
Definition: ibdr_pc11.vhd:71
regs_type := regs_init R_REGS
Definition: ibdr_pc11.vhd:121
integer := 6 pcsr_ibf_pie
Definition: ibdr_pc11.vhd:85
integer := 6 rcsr_ibf_rie
Definition: ibdr_pc11.vhd:72
integer := 8 pbuf_ibf_pval8
Definition: ibdr_pc11.vhd:89
integer := 15 rbuf_ibf_rbusy
Definition: ibdr_pc11.vhd:78
integer := 7 pcsr_ibf_prdy
Definition: ibdr_pc11.vhd:84
regs_type :=( '0', '1', '0', '0', '0',( others => '0'), '0', '0', '0', '1', '1', '0',( others => '0'), '0') regs_init
Definition: ibdr_pc11.vhd:108
slv2 := "10" ibaddr_pcsr
Definition: ibdr_pc11.vhd:66
slv2 := "11" ibaddr_pbuf
Definition: ibdr_pc11.vhd:67
in RESET slbit
Definition: ibdr_pc11.vhd:48
in BRESET slbit
Definition: ibdr_pc11.vhd:49
out EI_REQ_PTP slbit
Definition: ibdr_pc11.vhd:54
out RB_LAM slbit
Definition: ibdr_pc11.vhd:50
in CLK slbit
Definition: ibdr_pc11.vhd:47
in EI_ACK_PTP slbit
Definition: ibdr_pc11.vhd:57
in IB_MREQ ib_mreq_type
Definition: ibdr_pc11.vhd:51
in EI_ACK_PTR slbit
Definition: ibdr_pc11.vhd:55
out IB_SRES ib_sres_type
Definition: ibdr_pc11.vhd:52
out EI_REQ_PTR slbit
Definition: ibdr_pc11.vhd:53
Definition: iblib.vhd:33
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 7 downto 0) slv8
Definition: slvtypes.vhd:40
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31