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

Subversion Repositories w11

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

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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