w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
pdp11_core_rbus.vhd
Go to the documentation of this file.
1-- $Id: pdp11_core_rbus.vhd 1310 2022-10-27 16:15:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2007-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: pdp11_core_rbus - syn
7-- Description: pdp11: core to rbus interface
8--
9-- Dependencies: -
10-- Test bench: tb/tb_rlink_tba_pdp11core
11--
12-- Target Devices: generic
13-- Tool versions: ise 8.2-14.7; viv 2014.4-2019.1; ghdl 0.18-0.35
14--
15-- Synthesized (xst):
16-- Date Rev ise Target flop lutl lutm slic t peri
17-- 2014-12-21 591 14.7 131013 xc6slx16-2 52 118 0 58 s 4.9
18--
19-- Revision History: -
20-- Date Rev Version Comment
21-- 2019-06-02 1159 1.5.4 use rbaddr_ constants
22-- 2019-03-02 1116 1.5.3 rename state field rbinit to greset
23-- 2016-05-22 767 1.5.2 don't init N_REGS (vivado fix for fsm inference)
24-- 2015-07-10 700 1.5.1 add cpuact logic, redefine lam as cpuact 1->0
25-- 2015-05-09 677 1.5 start/stop/suspend overhaul; reset overhaul
26-- 2014-12-26 621 1.4 use full size 4k word ibus window
27-- 2014-12-21 617 1.3.1 use separate RB_STAT bits for cmderr and cmdmerr
28-- 2014-09-05 591 1.3 use new rlink v4 iface and 4 bit STAT
29-- 2014-08-15 583 1.2 rb_mreq addr now 16 bit
30-- 2011-11-18 427 1.1.1 now numeric_std clean
31-- 2010-12-29 351 1.1 renamed from pdp11_core_rri; ported to rbv3
32-- 2010-10-23 335 1.2.3 rename RRI_LAM->RB_LAM;
33-- 2010-06-20 308 1.2.2 use c_ibrb_ibf_ def's
34-- 2010-06-18 306 1.2.1 rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS;
35-- add ibrb register and ibr window logic
36-- 2010-06-13 305 1.2 add CP_ADDR in port; mostly rewritten for new
37-- rri <-> cp mapping
38-- 2010-06-03 299 1.1.2 correct rbus init logic (use we, din, RB_ADDR)
39-- 2010-05-02 287 1.1.1 rename RP_STAT->RB_STAT; remove unneeded unsigned()
40-- 2010-05-01 285 1.1 port to rri V2 interface, add RB_ADDR generic;
41-- rename c_rp_addr_* -> c_rb_addr_*
42-- 2008-05-03 143 1.0.8 rename _cpursta->_cpurust
43-- 2008-04-27 140 1.0.7 use cpursta interface, remove cpufail
44-- 2008-03-02 121 1.0.6 set RP_ERR when cmderr or cmdmerr status seen
45-- 2008-02-24 119 1.0.5 support lah,rps,wps cp commands
46-- 2008-01-20 113 1.0.4 use single LAM; change to RRI_LAM interface
47-- 2007-10-12 88 1.0.3 avoid ieee.std_logic_unsigned, use cast to unsigned
48-- 2007-08-16 74 1.0.2 add AP_LAM interface to pdp11_core_rri
49-- 2007-08-12 73 1.0.1 use def's; add stat command; wait for step complete
50-- 2007-07-08 65 1.0 Initial version
51------------------------------------------------------------------------------
52--
53-- rbus registers:
54--
55-- Addr Bits Name r/w/f Function
56--
57-- 00000 conf r/w/- cpu configuration (e.g. cpu type)
58-- (currently unused, all bits MBZ)
59-- 00001 cntl -/f/- cpu control
60-- 3:00 func function code
61-- 0000: noop
62-- 0001: start
63-- 0010: stop
64-- 0011: step
65-- 0100: creset
66-- 0101: breset
67-- 0110: suspend
68-- 0111: resume
69-- 00010 stat r/-/- cpu status
70-- 9 suspext r/-/- cp_stat: statext
71-- 8 suspint r/-/- cp_stat: statint
72-- 7:04 cpurust r/-/- cp_stat: cpurust
73-- 3 cpususp r/-/- cp_stat: cpususp
74-- 2 cpugo r/-/- cp_stat: cpugo
75-- 1 cmdmerr r/-/- cp_stat: cmdmerr
76-- 0 cmderr r/-/- cp_stat: cmderr
77-- 00011 psw r/w/- processor status word access
78-- 00100 al r/w/- address register, low
79-- 00101 ah r/w/- address register, high
80-- 7 ubm r/w/- ubmap access
81-- 6 p22 r/w/- 22bit access
82-- 5:00 addr r/w/- addr(21:16)
83-- 00110 mem r/w/- memory access
84-- 00111 memi r/w/- memory access, inc address
85-- 01rrr gr[] r/w/- general regs
86-- 10000 membe r/w/- memory write byte enables
87-- 3 stick r/w/- sticky flag
88-- 1:00 be r/w/- byte enables
89--
90
91library ieee;
92use ieee.std_logic_1164.all;
93use ieee.numeric_std.all;
94
95use work.slvtypes.all;
96use work.rblib.all;
97use work.pdp11.all;
98
99-- ----------------------------------------------------------------------------
100
101entity pdp11_core_rbus is -- core to rbus interface
102 generic (
103 RB_ADDR_CORE : slv16 := rbaddr_cpu0_core;
104 RB_ADDR_IBUS : slv16 := rbaddr_cpu0_ibus);
105 port (
106 CLK : in slbit; -- clock
107 RESET : in slbit; -- reset
108 RB_MREQ : in rb_mreq_type; -- rbus: request
109 RB_SRES : out rb_sres_type; -- rbus: response
110 RB_STAT : out slv4; -- rbus: status flags
111 RB_LAM : out slbit; -- remote attention
112 GRESET : out slbit; -- general reset
113 CP_CNTL : out cp_cntl_type; -- console control port
114 CP_ADDR : out cp_addr_type; -- console address port
115 CP_DIN : out slv16; -- console data in
116 CP_STAT : in cp_stat_type; -- console status port
117 CP_DOUT : in slv16 -- console data out
118 );
120
121
122architecture syn of pdp11_core_rbus is
123
124 type state_type is (
125 s_idle, -- s_idle: wait for rbus access
126 s_cpwait, -- s_cpwait: wait for cp port ack
127 s_cpstep -- s_cpstep: wait for cpustep done
128 );
129
130 type regs_type is record
131 state : state_type; -- state
132 rbselc : slbit; -- rbus select for core
133 rbseli : slbit; -- rbus select for ibus
134 greset : slbit; -- greset from rbus init (1 cycle pulse)
135 cpreq : slbit; -- cp request flag
136 cpfunc : slv5; -- cp function
137 cpuact_1 : slbit; -- prev cycle cpuact
138 addr : slv22_1; -- address register
139 ena_22bit : slbit; -- 22bit enable
140 ena_ubmap : slbit; -- ubmap enable
141 membe : slv2; -- memory write byte enables
142 membestick : slbit; -- memory write byte enables sticky
143 doinc : slbit; -- at cmdack: do addr reg inc
144 waitstep : slbit; -- at cmdack: wait for cpu step complete
145 end record regs_type;
146
147 constant regs_init : regs_type := (
148 s_idle, -- state
149 '0','0', -- rbselc,rbseli
150 '0', -- greset
151 '0', -- cpreq
152 (others=>'0'), -- cpfunc
153 '0', -- cpuact_1
154 (others=>'0'), -- addr
155 '0','0', -- ena_22bit, ena_ubmap
156 "11",'0', -- membe,membestick
157 '0','0' -- doinc, waitstep
158 );
159
161 signal N_REGS : regs_type; -- don't init (vivado fix for fsm infer)
162
163 begin
164
165 proc_regs: process (CLK)
166 begin
167
168 if rising_edge(CLK) then
169 if RESET = '1' then
170 R_REGS <= regs_init;
171 else
172 R_REGS <= N_REGS;
173 end if;
174 end if;
175
176 end process proc_regs;
177
178 proc_next: process (R_REGS, RB_MREQ, CP_STAT, CP_DOUT)
179
180 variable r : regs_type := regs_init;
181 variable n : regs_type := regs_init;
182
183 variable irb_ack : slbit := '0';
184 variable irb_busy : slbit := '0';
185 variable irb_err : slbit := '0';
186 variable irb_dout : slv16 := (others=>'0');
187 variable irb_lam : slbit := '0';
188 variable irbena : slbit := '0';
189
190 variable icpuact : slbit := '0';
191 variable icpreq : slbit := '0';
192 variable icpaddr : cp_addr_type := cp_addr_init;
193
194 begin
195
196 r := R_REGS;
197 n := R_REGS;
198
199 irb_ack := '0';
200 irb_busy := '0';
201 irb_err := '0';
202 irb_dout := (others=>'0');
203 irb_lam := '0';
204
205 irbena := RB_MREQ.re or RB_MREQ.we;
206
207 icpreq := '0';
208
209 -- generate single cycle pulse in case init against rbus base address seen
210 -- is used to generate some state machine resets via GRESET
211 n.greset := '0';
212 if RB_MREQ.init='1' and RB_MREQ.addr=RB_ADDR_CORE then
213 n.greset := RB_MREQ.din(c_init_rbf_greset);
214 end if;
215
216 -- rbus address decoder
217 n.rbseli := '0';
218 n.rbselc := '0';
219 if RB_MREQ.aval='1' then
220 if RB_MREQ.addr(15 downto 5)=RB_ADDR_CORE(15 downto 5) then
221 n.rbselc := '1';
222 end if;
223 if RB_MREQ.addr(15 downto 12)=RB_ADDR_IBUS(15 downto 12) then
224 n.rbseli := '1';
225 end if;
226 end if;
227
228 if (r.rbselc='1' or r.rbseli='1') and irbena='1' then
229 irb_ack := '1'; -- ack all (maybe rejected later)
230 end if;
231
232 case r.state is
233
234 when s_idle => -- s_idle: wait for rbus access ------
235
236 n.doinc := '0';
237 n.waitstep := '0';
238
239 if r.rbseli = '1' then
240 if irbena = '1' then
241 n.cpfunc := c_cpfunc_rmem;
242 n.cpfunc(0) := RB_MREQ.we;
243 icpreq := '1';
244 end if;
245
246 elsif r.rbselc = '1' then
247
248 case RB_MREQ.addr(4 downto 0) is
249
250 when c_rbaddr_conf => -- conf -------------------------
251 null; -- currently no action
252
253 when c_rbaddr_cntl => -- cntl -------------------------
254 if irbena = '1' then
255 n.cpfunc := RB_MREQ.din(n.cpfunc'range);
256 end if;
257 if RB_MREQ.we = '1' then
258 icpreq := '1';
259 if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
260 n.waitstep := '1';
261 end if;
262 end if;
263
264 when c_rbaddr_stat => -- stat ------------------
265 irb_dout(c_stat_rbf_suspext) := CP_STAT.suspext;
266 irb_dout(c_stat_rbf_suspint) := CP_STAT.suspint;
267 irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
268 irb_dout(c_stat_rbf_cpususp) := CP_STAT.cpususp;
269 irb_dout(c_stat_rbf_cpugo) := CP_STAT.cpugo;
270 irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
271 irb_dout(c_stat_rbf_cmderr) := CP_STAT.cmderr;
272
273 when c_rbaddr_psw => -- psw -------------------
274 if irbena = '1' then
275 n.cpfunc := c_cpfunc_rpsw;
276 n.cpfunc(0) := RB_MREQ.we;
277 icpreq := '1';
278 end if;
279
280 when c_rbaddr_al => -- al --------------------
281 irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
282 if RB_MREQ.we = '1' then
283 n.addr := (others=>'0'); -- write to al clears ah !!
284 n.ena_22bit := '0';
285 n.ena_ubmap := '0';
286 n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
287 end if;
288
289 when c_rbaddr_ah => -- ah --------------------
290 irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
291 irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
292 irb_dout(c_ah_rbf_addr) := r.addr(21 downto 16);
293 if RB_MREQ.we = '1' then
294 n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
295 n.ena_22bit := RB_MREQ.din(c_ah_rbf_ena_22bit);
296 n.ena_ubmap := RB_MREQ.din(c_ah_rbf_ena_ubmap);
297 end if;
298
299 when c_rbaddr_mem => -- mem -------------------
300 if irbena = '1' then
301 n.cpfunc := c_cpfunc_rmem;
302 n.cpfunc(0) := RB_MREQ.we;
303 icpreq := '1';
304 end if;
305
306 when c_rbaddr_memi => -- memi ------------------
307 if irbena = '1' then
308 n.cpfunc := c_cpfunc_rmem;
309 n.cpfunc(0) := RB_MREQ.we;
310 n.doinc := '1';
311 icpreq := '1';
312 end if;
313
314 when c_rbaddr_r0 | c_rbaddr_r1 |
315 c_rbaddr_r2 | c_rbaddr_r3 |
316 c_rbaddr_r4 | c_rbaddr_r5 |
317 c_rbaddr_sp | c_rbaddr_pc => -- r* -----------------
318 if irbena = '1' then
319 n.cpfunc := c_cpfunc_rreg;
320 n.cpfunc(0) := RB_MREQ.we;
321 icpreq := '1';
322 end if;
323
324 when c_rbaddr_membe => -- membe -----------------
325 irb_dout(c_membe_rbf_be) := r.membe;
326 irb_dout(c_membe_rbf_stick) := r.membestick;
327 if RB_MREQ.we = '1' then
328 n.membe := RB_MREQ.din(c_membe_rbf_be);
329 n.membestick := RB_MREQ.din(c_membe_rbf_stick);
330 end if;
331
332 when others =>
333 irb_ack := '0';
334
335 end case;
336
337 end if;
338
339 if icpreq = '1' then
340 irb_busy := '1';
341 n.cpreq := '1';
342 n.state := s_cpwait;
343 end if;
344
345 when s_cpwait => -- s_cpwait: wait for cp port ack ----
346 n.cpreq := '0'; -- cpreq only for 1 cycle
347
348 if (r.rbselc or r.rbseli)='0' or irbena='0' then -- rbus cycle abort
349 if r.cpfunc = c_cpfunc_wmem and -- if wmem command
350 r.membestick = '0' then -- and be's not sticky
351 n.membe := "11"; -- re-enable both bytes
352 end if;
353 n.state := s_idle; -- quit
354 else
355 irb_dout := CP_DOUT;
356 irb_err := CP_STAT.cmderr or CP_STAT.cmdmerr;
357 if CP_STAT.cmdack = '1' then -- normal cycle end
358 if r.cpfunc = c_cpfunc_wmem and -- if wmem command
359 r.membestick = '0' then -- and be's not sticky
360 n.membe := "11"; -- re-enable both bytes
361 end if;
362 if r.doinc = '1' then
363 n.addr := slv(unsigned(r.addr) + 1);
364 end if;
365 if r.waitstep = '1' then
366 irb_busy := '1';
367 n.state := s_cpstep;
368 else
369 n.state := s_idle;
370 end if;
371 else
372 irb_busy := '1';
373 end if;
374 end if;
375
376 when s_cpstep => -- s_cpstep: wait for cpustep done ---
377 n.state := s_cpstep; -- needed to prevent vivado iSTATE
378 if r.rbselc='0' or irbena='0' then -- rbus cycle abort
379 n.state := s_idle; -- quit
380 else
381 if CP_STAT.cpustep = '0' then -- cpustep done
382 n.state := s_idle;
383 else
384 irb_busy := '1';
385 end if;
386 end if;
387
388 when others => null;
389 end case;
390
391 icpaddr := cp_addr_init;
392 icpaddr.be := r.membe;
393
394 if r.rbseli = '0' then -- access via cp
395 icpaddr.addr := r.addr;
396 icpaddr.racc := '0';
397 icpaddr.ena_22bit := r.ena_22bit;
398 icpaddr.ena_ubmap := r.ena_ubmap;
399 else -- access via ibus window
400 icpaddr.addr(15 downto 13) := "111";
401 icpaddr.addr(12 downto 1) := RB_MREQ.addr(11 downto 0);
402 icpaddr.racc := '1';
403 icpaddr.ena_22bit := '0';
404 icpaddr.ena_ubmap := '0';
405 end if;
406
407 icpuact := CP_STAT.cpugo and not CP_STAT.suspint;
408 n.cpuact_1 := icpuact; -- delay cpuact
409 if (r.cpuact_1='1' and icpuact='0') then -- cpuact 1 -> 0
410 irb_lam := '1';
411 end if;
412
413 N_REGS <= n;
414
415 RB_SRES.ack <= irb_ack;
416 RB_SRES.err <= irb_err;
417 RB_SRES.busy <= irb_busy;
418 RB_SRES.dout <= irb_dout;
419
420 RB_STAT(3) <= CP_STAT.cmderr;
421 RB_STAT(2) <= CP_STAT.cmdmerr;
422 RB_STAT(1) <= CP_STAT.cpususp;
423 RB_STAT(0) <= CP_STAT.cpugo;
424
425 RB_LAM <= irb_lam;
426
427 GRESET <= R_REGS.greset;
428
429 CP_CNTL.req <= r.cpreq;
430 CP_CNTL.func <= r.cpfunc;
431 CP_CNTL.rnum <= RB_MREQ.addr(2 downto 0);
432
433 CP_ADDR <= icpaddr;
434 CP_DIN <= RB_MREQ.din;
435
436 end process proc_next;
437
438end syn;
regs_type :=( s_idle, '0', '0', '0', '0',( others => '0'), '0',( others => '0'), '0', '0', "11", '0', '0', '0') regs_init
(s_idle,s_cpwait,s_cpstep) state_type
regs_type := regs_init R_REGS
in CP_STAT cp_stat_type
out CP_CNTL cp_cntl_type
in RB_MREQ rb_mreq_type
out CP_ADDR cp_addr_type
RB_ADDR_CORE slv16 := rbaddr_cpu0_core
RB_ADDR_IBUS slv16 := rbaddr_cpu0_ibus
out RB_SRES rb_sres_type
Definition: pdp11.vhd:123
Definition: rblib.vhd:32
std_logic_vector( 21 downto 1) slv22_1
Definition: slvtypes.vhd:69
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 4 downto 0) slv5
Definition: slvtypes.vhd:37
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31