OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [rtl/] [w11a/] [pdp11_core_rbus.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 wfjm
-- $Id: pdp11_core_rbus.vhd 553 2014-03-17 06:40:08Z mueller $
2 2 wfjm
--
3 22 wfjm
-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15 9 wfjm
-- Module Name:    pdp11_core_rbus - syn
16
-- Description:    pdp11: core to rbus interface
17 2 wfjm
--
18
-- Dependencies:   -
19 9 wfjm
-- Test bench:     tb/tb_rlink_tba_pdp11core
20 2 wfjm
--
21
-- Target Devices: generic
22 13 wfjm
-- Tool versions:  xst 8.2, 9.1, 9.2, 11.4, 12.1, 13.1; ghdl 0.18-0.29
23 2 wfjm
-- Revision History: -
24
-- Date         Rev Version  Comment
25 13 wfjm
-- 2011-11-18   427   1.1.1  now numeric_std clean
26 9 wfjm
-- 2010-12-29   351   1.1    renamed from pdp11_core_rri; ported to rbv3
27 8 wfjm
-- 2010-10-23   335   1.2.3  rename RRI_LAM->RB_LAM;
28 2 wfjm
-- 2010-06-20   308   1.2.2  use c_ibrb_ibf_ def's
29
-- 2010-06-18   306   1.2.1  rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS;
30
--                           add ibrb register and ibr window logic
31
-- 2010-06-13   305   1.2    add CP_ADDR in port; mostly rewritten for new
32
--                           rri <-> cp mapping
33
-- 2010-06-03   299   1.1.2  correct rbus init logic (use we, din, RB_ADDR)
34
-- 2010-05-02   287   1.1.1  rename RP_STAT->RB_STAT; remove unneeded unsigned()
35
-- 2010-05-01   285   1.1    port to rri V2 interface, add RB_ADDR generic;
36
--                           rename c_rp_addr_* -> c_rb_addr_*
37
-- 2008-05-03   143   1.0.8  rename _cpursta->_cpurust
38
-- 2008-04-27   140   1.0.7  use cpursta interface, remove cpufail
39
-- 2008-03-02   121   1.0.6  set RP_ERR when cmderr or cmdmerr status seen
40
-- 2008-02-24   119   1.0.5  support lah,rps,wps cp commands
41
-- 2008-01-20   113   1.0.4  use single LAM; change to RRI_LAM interface
42
-- 2007-10-12    88   1.0.3  avoid ieee.std_logic_unsigned, use cast to unsigned
43
-- 2007-08-16    74   1.0.2  add AP_LAM interface to pdp11_core_rri
44
-- 2007-08-12    73   1.0.1  use def's; add stat command; wait for step complete
45
-- 2007-07-08    65   1.0    Initial version 
46
------------------------------------------------------------------------------
47
--
48
-- rbus registers:
49
--
50
-- Address   Bits Name        r/w/i  Function
51
--
52
-- bbb00000       conf        r/w/-  cpu configuration (e.g. cpu type)
53
--                                   (currently unused, all bits MBZ)
54
-- bbb00001       cntl        -/f/-  cpu control
55
--            3:0   func               function code
56
--                                       0000: noop
57
--                                       0001: start
58
--                                       0010: stop
59
--                                       0011: continue
60
--                                       0100: step
61
--                                       1111: reset (soft)
62
-- bbb00010       stat        r/-/-  cpu status
63
--           7:04   cpurust   r/-/-    cp_stat: cpurust
64
--              3   cpuhalt   r/-/-    cp_stat: cpuhalt
65
--              2   cpugo     r/-/-    cp_stat: cpugo
66
--              1   cmdmerr   r/-/-    cp_stat: cmdmerr
67
--              0   cmderr    r/-/-    cp_stat: cmderr
68
-- bbb00011       psw         r/w/-  processor status word access
69
-- bbb00100       al          r/w/-  address register, low
70
-- bbb00101       ah          r/w/-  address register, high
71 22 wfjm
--              7   ubm       r/w/-    ubmap access
72
--              6   p22       r/w/-    22bit access
73
--           5: 0   addr      r/w/-    addr(21:16)  
74 2 wfjm
-- bbb00110       mem         r/w/-  memory access
75
-- bbb00111       memi        r/w/-  memory access, inc address
76
-- bbb01rrr       gpr[]       r/w/-  general purpose regs
77
-- bbb10000       ibrb        r/w/-  ibr base address
78
--          12:06   base      r/w/-    ibr window base address
79
--           1:00   we        r/w/-    byte enables (00 equivalent to 11)
80
-- www-----       ibr[]       r/w/-  ibr window (32 words)
81
--
82
 
83
library ieee;
84
use ieee.std_logic_1164.all;
85 13 wfjm
use ieee.numeric_std.all;
86 2 wfjm
 
87
use work.slvtypes.all;
88 9 wfjm
use work.rblib.all;
89 2 wfjm
use work.pdp11.all;
90
 
91
-- ----------------------------------------------------------------------------
92
 
93 9 wfjm
entity pdp11_core_rbus is               -- core to rbus interface
94 2 wfjm
  generic (
95 13 wfjm
    RB_ADDR_CORE : slv8 := slv(to_unsigned(2#00000000#,8));
96
    RB_ADDR_IBUS : slv8 := slv(to_unsigned(2#10000000#,8)));
97 2 wfjm
  port (
98
    CLK : in slbit;                     -- clock
99
    RESET : in slbit;                   -- reset
100
    RB_MREQ : in rb_mreq_type;          -- rbus: request
101
    RB_SRES : out rb_sres_type;         -- rbus: response
102
    RB_STAT : out slv3;                 -- rbus: status flags
103 8 wfjm
    RB_LAM : out slbit;                 -- remote attention
104 2 wfjm
    CPU_RESET : out slbit;              -- cpu master reset
105
    CP_CNTL : out cp_cntl_type;         -- console control port
106
    CP_ADDR : out cp_addr_type;         -- console address port
107
    CP_DIN : out slv16;                 -- console data in
108
    CP_STAT : in cp_stat_type;          -- console status port
109
    CP_DOUT : in slv16                  -- console data out
110
  );
111 9 wfjm
end pdp11_core_rbus;
112 2 wfjm
 
113
 
114 9 wfjm
architecture syn of pdp11_core_rbus is
115 2 wfjm
 
116
  type state_type is (
117
    s_idle,                             -- s_idle: wait for rp access
118
    s_cpwait,                           -- s_cpwait: wait for cp port ack
119
    s_cpstep                            -- s_cpstep: wait for cpustep done
120
  );
121
 
122
  type regs_type is record
123
    state : state_type;                 -- state
124 9 wfjm
    rbselc : slbit;                     -- rbus select for core
125
    rbseli : slbit;                     -- rbus select for ibus
126 2 wfjm
    cpreq : slbit;                      -- cp request flag
127
    cpfunc : slv5;                      -- cp function
128
    cpugo_1 : slbit;                    -- prev cycle cpugo
129
    addr : slv22_1;                     -- address register
130
    ena_22bit : slbit;                  -- 22bit enable
131
    ena_ubmap : slbit;                  -- ubmap enable
132
    ibrbase : slv(c_ibrb_ibf_base);     -- ibr base address
133
    ibrbe : slv2;                       -- ibr byte enables
134
    ibrberet : slv2;                    -- ibr byte enables (for readback)
135
    doinc : slbit;                      -- at cmdack: do addr reg inc
136
    waitstep : slbit;                   -- at cmdack: wait for cpu step complete
137
  end record regs_type;
138
 
139
  constant regs_init : regs_type := (
140
    s_idle,                             -- state
141 9 wfjm
    '0','0',                            -- rbselc,rbseli
142 2 wfjm
    '0',                                -- cpreq
143
    (others=>'0'),                      -- cpfunc
144
    '0',                                -- cpugo_1
145
    (others=>'0'),                      -- addr
146
    '0','0',                            -- ena_22bit, ena_ubmap
147
    (others=>'0'),"00","00",            -- ibrbase, ibrbe, ibrberet
148
    '0','0'                             -- doinc, waitstep
149
  );
150
 
151
  signal R_REGS : regs_type := regs_init;  -- state registers
152
  signal N_REGS : regs_type := regs_init;  -- next value state regs
153
 
154
  begin
155
 
156
  proc_regs: process (CLK)
157
  begin
158
 
159 13 wfjm
    if rising_edge(CLK) then
160 2 wfjm
      if RESET = '1' then
161
        R_REGS <= regs_init;
162
      else
163
        R_REGS <= N_REGS;
164
      end if;
165
    end if;
166
 
167
  end process proc_regs;
168
 
169
  proc_next: process (R_REGS, RB_MREQ, CP_STAT, CP_DOUT)
170
 
171
    variable r : regs_type := regs_init;
172
    variable n : regs_type := regs_init;
173
 
174
    variable irb_ack  : slbit := '0';
175
    variable irb_busy : slbit := '0';
176
    variable irb_err  : slbit := '0';
177
    variable irb_dout : slv16 := (others=>'0');
178
    variable irb_lam  : slbit := '0';
179 9 wfjm
    variable irbena   : slbit := '0';
180 2 wfjm
 
181
    variable icpreq    : slbit := '0';
182
    variable icpureset : slbit := '0';
183
    variable icpaddr   : cp_addr_type := cp_addr_init;
184
 
185
  begin
186
 
187
    r := R_REGS;
188
    n := R_REGS;
189
 
190
    irb_ack  := '0';
191
    irb_busy := '0';
192
    irb_err  := '0';
193
    irb_dout := (others=>'0');
194
    irb_lam  := '0';
195 9 wfjm
 
196
    irbena  := RB_MREQ.re or RB_MREQ.we;
197
 
198 2 wfjm
    icpreq    := '0';
199
    icpureset := '0';
200
 
201 9 wfjm
    -- look for init's against the rbus base address, generate subsystem resets
202
    if RB_MREQ.init='1' and RB_MREQ.we='1' and RB_MREQ.addr=RB_ADDR_CORE then
203
      icpureset := RB_MREQ.din(0);
204
    end if;
205
 
206
    -- rbus address decoder
207
    n.rbseli := '0';
208
    n.rbselc := '0';
209
    if RB_MREQ.aval='1' then
210 2 wfjm
      if RB_MREQ.addr(7 downto 5)=RB_ADDR_CORE(7 downto 5) then
211 9 wfjm
        n.rbselc := '1';
212 2 wfjm
      end if;
213
      if RB_MREQ.addr(7 downto 5)=RB_ADDR_IBUS(7 downto 5) then
214 9 wfjm
        n.rbseli := '1';
215 2 wfjm
      end if;
216
    end if;
217
 
218 9 wfjm
    if (r.rbselc='1' or r.rbseli='1') and irbena='1' then
219
      irb_ack  := '1';                   -- ack all (maybe rejected later)
220
    end if;
221 2 wfjm
 
222
    case r.state is
223
 
224
      when s_idle =>                    -- s_idle: wait for rbus access ------
225
 
226
        n.doinc    := '0';
227
        n.waitstep := '0';
228
 
229 9 wfjm
        if r.rbseli = '1' then
230
          if irbena = '1' then
231
            n.cpfunc    := c_cpfunc_rmem;
232
            n.cpfunc(0) := RB_MREQ.we;
233
            icpreq := '1';
234
          end if;
235 2 wfjm
 
236 9 wfjm
        elsif r.rbselc = '1' then
237 2 wfjm
 
238
          case RB_MREQ.addr(4 downto 0) is
239
 
240
            when c_rbaddr_conf =>         -- conf -------------------------
241
              null;                         -- currently no action
242
 
243
            when c_rbaddr_cntl =>         -- cntl -------------------------
244 9 wfjm
              if irbena = '1' then
245
                n.cpfunc := RB_MREQ.din(n.cpfunc'range);
246
              end if;
247 2 wfjm
              if RB_MREQ.we = '1' then
248
                icpreq := '1';
249
                if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
250
                  n.waitstep := '1';
251
                end if;
252
              end if;
253
 
254
            when c_rbaddr_stat =>         -- stat -------------------------
255
              irb_dout(c_stat_rbf_cmderr)  := CP_STAT.cmderr;
256
              irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
257
              irb_dout(c_stat_rbf_cpugo)   := CP_STAT.cpugo;
258
              irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt;
259
              irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
260
 
261
            when c_rbaddr_psw  =>         -- psw --------------------------
262 9 wfjm
              if irbena = '1' then
263
                n.cpfunc    := c_cpfunc_rpsw;
264
                n.cpfunc(0) := RB_MREQ.we;
265
                icpreq := '1';
266
              end if;
267 2 wfjm
 
268
            when c_rbaddr_al   =>         -- al ---------------------------
269
              irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
270
              if RB_MREQ.we = '1' then
271
                n.addr      := (others=>'0'); -- write to al clears ah !!
272
                n.ena_22bit := '0';
273
                n.ena_ubmap := '0';
274
                n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
275
              end if;
276
 
277
            when c_rbaddr_ah   =>         -- ah ---------------------------
278
              irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
279
              irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
280
              irb_dout(c_ah_rbf_addr)      := r.addr(21 downto 16);
281
              if RB_MREQ.we = '1' then
282
                n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
283
                n.ena_22bit          := RB_MREQ.din(c_ah_rbf_ena_22bit);
284
                n.ena_ubmap          := RB_MREQ.din(c_ah_rbf_ena_ubmap);
285
              end if;
286
 
287
            when c_rbaddr_mem  =>         -- mem -----------------
288 9 wfjm
              if irbena = '1' then
289
                n.cpfunc    := c_cpfunc_rmem;
290
                n.cpfunc(0) := RB_MREQ.we;
291
                icpreq   := '1';
292
              end if;
293
 
294 2 wfjm
            when c_rbaddr_memi  =>        -- memi ----------------
295 9 wfjm
              if irbena = '1' then
296
                n.cpfunc    := c_cpfunc_rmem;
297
                n.cpfunc(0) := RB_MREQ.we;
298
                n.doinc  := '1';
299
                icpreq   := '1';
300
              end if;
301 2 wfjm
 
302
            when c_rbaddr_r0 | c_rbaddr_r1 |
303
                 c_rbaddr_r2 | c_rbaddr_r3 |
304
                 c_rbaddr_r4 | c_rbaddr_r5 |
305
                 c_rbaddr_sp | c_rbaddr_pc =>      -- r* ------------------
306 9 wfjm
              if irbena = '1' then
307
                n.cpfunc    := c_cpfunc_rreg;
308
                n.cpfunc(0) := RB_MREQ.we;
309
                icpreq   := '1';
310
              end if;
311
 
312 2 wfjm
            when c_rbaddr_ibrb  =>        -- ibrb ----------------
313
              irb_dout(c_ibrb_ibf_base) := r.ibrbase;
314
              irb_dout(c_ibrb_ibf_be)   := r.ibrberet;
315
              if RB_MREQ.we = '1' then
316
                n.ibrbase  := RB_MREQ.din(c_ibrb_ibf_base);
317
                n.ibrberet := RB_MREQ.din(c_ibrb_ibf_be);
318
                if RB_MREQ.din(c_ibrb_ibf_be) = "00" then -- both be=0 ?
319
                  n.ibrbe := "11";
320
                else                               -- otherwise take 2 LSB's
321
                  n.ibrbe := RB_MREQ.din(c_ibrb_ibf_be);
322
                end if;
323
              end if;
324
 
325
            when others =>
326
              irb_ack := '0';
327
 
328
          end case;
329
 
330
        end if;
331
 
332
        if icpreq = '1' then
333
          irb_busy := '1';
334
          n.cpreq  := '1';
335
          n.state  := s_cpwait;
336
        end if;
337
 
338
      when s_cpwait =>                  -- s_cpwait: wait for cp port ack ----
339
        n.cpreq := '0';                   -- cpreq only for 1 cycle
340
 
341 9 wfjm
        if (r.rbselc or r.rbseli)='0' or irbena='0' then -- rbus cycle abort
342 2 wfjm
          n.state := s_idle;              -- quit
343
        else
344
          irb_dout := CP_DOUT;
345 9 wfjm
          irb_err  := CP_STAT.cmderr or CP_STAT.cmdmerr;
346 2 wfjm
          if CP_STAT.cmdack = '1' then       -- normal cycle end
347
            if r.doinc = '1' then
348 13 wfjm
              n.addr := slv(unsigned(r.addr) + 1);
349 2 wfjm
            end if;
350
            if r.waitstep = '1' then
351
              irb_busy := '1';
352
              n.state := s_cpstep;
353
            else
354
              n.state := s_idle;
355
            end if;
356
          else
357
            irb_busy := '1';
358
          end if;
359
        end if;
360
 
361
      when s_cpstep =>                  -- s_cpstep: wait for cpustep done ---
362 9 wfjm
        if r.rbselc='0' or irbena='0' then -- rbus cycle abort
363 2 wfjm
          n.state := s_idle;                -- quit
364
        else
365
          if CP_STAT.cpustep = '0' then      -- cpustep done
366
            n.state := s_idle;
367
          else
368
            irb_busy := '1';
369
          end if;
370
        end if;
371
 
372
      when others => null;
373
    end case;
374
 
375
    icpaddr := cp_addr_init;
376
    icpaddr.addr      := r.addr;
377
    icpaddr.racc      := '0';
378
    icpaddr.be        := "11";
379
    icpaddr.ena_22bit := r.ena_22bit;
380
    icpaddr.ena_ubmap := r.ena_ubmap;
381
 
382 9 wfjm
    if r.rbseli = '1' and irbena = '1' then
383 2 wfjm
      icpaddr.addr(15 downto 13)    := "111";
384
      icpaddr.addr(c_ibrb_ibf_base) := r.ibrbase;
385
      icpaddr.addr(5 downto 1)      := RB_MREQ.addr(4 downto 0);
386
      icpaddr.racc      := '1';
387
      icpaddr.be        := r.ibrbe;
388
      icpaddr.ena_22bit := '0';
389
      icpaddr.ena_ubmap := '0';
390
    end if;
391
 
392
    n.cpugo_1 := CP_STAT.cpugo;         -- delay cpugo 
393
    if CP_STAT.cpugo='0' and r.cpugo_1='1' then  -- cpugo 1 -> 0 transition ?
394
      irb_lam := '1';
395
    end if;
396
 
397
    N_REGS <= n;
398
 
399
    RB_SRES.ack  <= irb_ack;
400
    RB_SRES.err  <= irb_err;
401
    RB_SRES.busy <= irb_busy;
402
    RB_SRES.dout <= irb_dout;
403
 
404
    RB_STAT(0) <= CP_STAT.cpugo;
405
    RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left);
406
    RB_STAT(2) <= CP_STAT.cmderr  or CP_STAT.cmdmerr;
407
 
408 8 wfjm
    RB_LAM     <= irb_lam;
409 2 wfjm
 
410
    CPU_RESET  <= icpureset;
411
 
412
    CP_CNTL.req  <= r.cpreq;
413
    CP_CNTL.func <= r.cpfunc;
414
    CP_CNTL.rnum <= RB_MREQ.addr(2 downto 0);
415
 
416
    CP_ADDR <= icpaddr;
417
    CP_DIN  <= RB_MREQ.din;
418
 
419
  end process proc_next;
420
 
421
end syn;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.