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 8

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

Line No. Rev Author Line
1 8 wfjm
-- $Id: pdp11_core_rri.vhd 335 2010-10-24 22:24:23Z mueller $
2 2 wfjm
--
3
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
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
-- Module Name:    pdp11_core_rri - syn
16
-- Description:    pdp11: core to rri register port interface
17
--
18
-- Dependencies:   -
19
-- Test bench:     tb/tb_rritba_pdp11core
20
--                 tb/tb_rripdp_pdp11core
21
--                 tb/tb_rriext_pdp11core
22
--
23
-- Target Devices: generic
24 8 wfjm
-- Tool versions:  xst 8.1, 8.2, 9.1, 9.2, 11.4, 12.1; ghdl 0.18-0.26
25 2 wfjm
-- Revision History: -
26
-- Date         Rev Version  Comment
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
-- bbb00110       mem         r/w/-  memory access
72
-- bbb00111       memi        r/w/-  memory access, inc address
73
-- bbb01rrr       gpr[]       r/w/-  general purpose regs
74
-- bbb10000       ibrb        r/w/-  ibr base address
75
--          12:06   base      r/w/-    ibr window base address
76
--           1:00   we        r/w/-    byte enables (00 equivalent to 11)
77
-- www-----       ibr[]       r/w/-  ibr window (32 words)
78
--
79
 
80
library ieee;
81
use ieee.std_logic_1164.all;
82
use ieee.std_logic_arith.all;
83
 
84
use work.slvtypes.all;
85
use work.rrilib.all;
86
use work.pdp11.all;
87
 
88
-- ----------------------------------------------------------------------------
89
 
90
entity pdp11_core_rri is                -- core to rri reg port interface
91
  generic (
92
    RB_ADDR_CORE : slv8 := conv_std_logic_vector(2#00000000#,8);
93
    RB_ADDR_IBUS : slv8 := conv_std_logic_vector(2#10000000#,8));
94
  port (
95
    CLK : in slbit;                     -- clock
96
    RESET : in slbit;                   -- reset
97
    RB_MREQ : in rb_mreq_type;          -- rbus: request
98
    RB_SRES : out rb_sres_type;         -- rbus: response
99
    RB_STAT : out slv3;                 -- rbus: status flags
100 8 wfjm
    RB_LAM : out slbit;                 -- remote attention
101 2 wfjm
    CPU_RESET : out slbit;              -- cpu master reset
102
    CP_CNTL : out cp_cntl_type;         -- console control port
103
    CP_ADDR : out cp_addr_type;         -- console address port
104
    CP_DIN : out slv16;                 -- console data in
105
    CP_STAT : in cp_stat_type;          -- console status port
106
    CP_DOUT : in slv16                  -- console data out
107
  );
108
end pdp11_core_rri;
109
 
110
 
111
architecture syn of pdp11_core_rri is
112
 
113
  type state_type is (
114
    s_idle,                             -- s_idle: wait for rp access
115
    s_cpwait,                           -- s_cpwait: wait for cp port ack
116
    s_cpstep                            -- s_cpstep: wait for cpustep done
117
  );
118
 
119
  type regs_type is record
120
    state : state_type;                 -- state
121
    cpreq : slbit;                      -- cp request flag
122
    cpfunc : slv5;                      -- cp function
123
    cpugo_1 : slbit;                    -- prev cycle cpugo
124
    addr : slv22_1;                     -- address register
125
    ena_22bit : slbit;                  -- 22bit enable
126
    ena_ubmap : slbit;                  -- ubmap enable
127
    ibrbase : slv(c_ibrb_ibf_base);     -- ibr base address
128
    ibrbe : slv2;                       -- ibr byte enables
129
    ibrberet : slv2;                    -- ibr byte enables (for readback)
130
    doinc : slbit;                      -- at cmdack: do addr reg inc
131
    waitstep : slbit;                   -- at cmdack: wait for cpu step complete
132
  end record regs_type;
133
 
134
  constant regs_init : regs_type := (
135
    s_idle,                             -- state
136
    '0',                                -- cpreq
137
    (others=>'0'),                      -- cpfunc
138
    '0',                                -- cpugo_1
139
    (others=>'0'),                      -- addr
140
    '0','0',                            -- ena_22bit, ena_ubmap
141
    (others=>'0'),"00","00",            -- ibrbase, ibrbe, ibrberet
142
    '0','0'                             -- doinc, waitstep
143
  );
144
 
145
  signal R_REGS : regs_type := regs_init;  -- state registers
146
  signal N_REGS : regs_type := regs_init;  -- next value state regs
147
 
148
  begin
149
 
150
  proc_regs: process (CLK)
151
  begin
152
 
153
    if CLK'event and CLK='1' then
154
      if RESET = '1' then
155
        R_REGS <= regs_init;
156
      else
157
        R_REGS <= N_REGS;
158
      end if;
159
    end if;
160
 
161
  end process proc_regs;
162
 
163
  proc_next: process (R_REGS, RB_MREQ, CP_STAT, CP_DOUT)
164
 
165
    variable r : regs_type := regs_init;
166
    variable n : regs_type := regs_init;
167
 
168
    variable irb_selc : slbit := '0';
169
    variable irb_seli : slbit := '0';
170
    variable irb_ack  : slbit := '0';
171
    variable irb_busy : slbit := '0';
172
    variable irb_err  : slbit := '0';
173
    variable irb_dout : slv16 := (others=>'0');
174
    variable irb_lam  : slbit := '0';
175
 
176
    variable icpreq    : slbit := '0';
177
    variable icpureset : slbit := '0';
178
    variable icpaddr   : cp_addr_type := cp_addr_init;
179
 
180
  begin
181
 
182
    r := R_REGS;
183
    n := R_REGS;
184
 
185
    irb_selc := '0';
186
    irb_seli := '0';
187
    irb_ack  := '0';
188
    irb_busy := '0';
189
    irb_err  := '0';
190
    irb_dout := (others=>'0');
191
    irb_lam  := '0';
192
 
193
    icpreq    := '0';
194
    icpureset := '0';
195
 
196
    if RB_MREQ.req='1' then
197
      if RB_MREQ.addr(7 downto 5)=RB_ADDR_CORE(7 downto 5) then
198
        irb_selc := '1';
199
        irb_ack  := '1';                   -- ack all, unless reject or busy
200
      end if;
201
      if RB_MREQ.addr(7 downto 5)=RB_ADDR_IBUS(7 downto 5) then
202
        irb_seli := '1';
203
        irb_ack  := '1';                   -- ack all, unless reject or busy
204
      end if;
205
    end if;
206
 
207
    -- look for init's against the rbus base address, generate subsystem resets
208
    if RB_MREQ.init='1' and RB_MREQ.we='1' and RB_MREQ.addr=RB_ADDR_CORE then
209
      icpureset := RB_MREQ.din(0);
210
    end if;
211
 
212
    case r.state is
213
 
214
      when s_idle =>                    -- s_idle: wait for rbus access ------
215
 
216
        n.doinc    := '0';
217
        n.waitstep := '0';
218
 
219
        if irb_seli = '1' then
220
          n.cpfunc    := c_cpfunc_rmem;
221
          n.cpfunc(0) := RB_MREQ.we;
222
          icpreq := '1';
223
 
224
        elsif irb_selc = '1' then
225
 
226
          case RB_MREQ.addr(4 downto 0) is
227
 
228
            when c_rbaddr_conf =>         -- conf -------------------------
229
              null;                         -- currently no action
230
 
231
            when c_rbaddr_cntl =>         -- cntl -------------------------
232
              n.cpfunc := RB_MREQ.din(n.cpfunc'range);
233
              if RB_MREQ.we = '1' then
234
                icpreq := '1';
235
                if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then
236
                  n.waitstep := '1';
237
                end if;
238
              end if;
239
 
240
            when c_rbaddr_stat =>         -- stat -------------------------
241
              irb_dout(c_stat_rbf_cmderr)  := CP_STAT.cmderr;
242
              irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr;
243
              irb_dout(c_stat_rbf_cpugo)   := CP_STAT.cpugo;
244
              irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt;
245
              irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust;
246
 
247
            when c_rbaddr_psw  =>         -- psw --------------------------
248
              n.cpfunc    := c_cpfunc_rpsw;
249
              n.cpfunc(0) := RB_MREQ.we;
250
              icpreq := '1';
251
 
252
            when c_rbaddr_al   =>         -- al ---------------------------
253
              irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr);
254
              if RB_MREQ.we = '1' then
255
                n.addr      := (others=>'0'); -- write to al clears ah !!
256
                n.ena_22bit := '0';
257
                n.ena_ubmap := '0';
258
                n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr);
259
              end if;
260
 
261
            when c_rbaddr_ah   =>         -- ah ---------------------------
262
              irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap;
263
              irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit;
264
              irb_dout(c_ah_rbf_addr)      := r.addr(21 downto 16);
265
              if RB_MREQ.we = '1' then
266
                n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr);
267
                n.ena_22bit          := RB_MREQ.din(c_ah_rbf_ena_22bit);
268
                n.ena_ubmap          := RB_MREQ.din(c_ah_rbf_ena_ubmap);
269
              end if;
270
 
271
            when c_rbaddr_mem  =>         -- mem -----------------
272
              n.cpfunc    := c_cpfunc_rmem;
273
              n.cpfunc(0) := RB_MREQ.we;
274
              icpreq   := '1';
275
 
276
            when c_rbaddr_memi  =>        -- memi ----------------
277
              n.cpfunc    := c_cpfunc_rmem;
278
              n.cpfunc(0) := RB_MREQ.we;
279
              n.doinc  := '1';
280
              icpreq   := '1';
281
 
282
            when c_rbaddr_r0 | c_rbaddr_r1 |
283
                 c_rbaddr_r2 | c_rbaddr_r3 |
284
                 c_rbaddr_r4 | c_rbaddr_r5 |
285
                 c_rbaddr_sp | c_rbaddr_pc =>      -- r* ------------------
286
              n.cpfunc    := c_cpfunc_rreg;
287
              n.cpfunc(0) := RB_MREQ.we;
288
              icpreq   := '1';
289
 
290
            when c_rbaddr_ibrb  =>        -- ibrb ----------------
291
              irb_dout(c_ibrb_ibf_base) := r.ibrbase;
292
              irb_dout(c_ibrb_ibf_be)   := r.ibrberet;
293
              if RB_MREQ.we = '1' then
294
                n.ibrbase  := RB_MREQ.din(c_ibrb_ibf_base);
295
                n.ibrberet := RB_MREQ.din(c_ibrb_ibf_be);
296
                if RB_MREQ.din(c_ibrb_ibf_be) = "00" then -- both be=0 ?
297
                  n.ibrbe := "11";
298
                else                               -- otherwise take 2 LSB's
299
                  n.ibrbe := RB_MREQ.din(c_ibrb_ibf_be);
300
                end if;
301
              end if;
302
 
303
            when others =>
304
              irb_ack := '0';
305
 
306
          end case;
307
 
308
        end if;
309
 
310
        if icpreq = '1' then
311
          irb_busy := '1';
312
          n.cpreq  := '1';
313
          n.state  := s_cpwait;
314
        end if;
315
 
316
      when s_cpwait =>                  -- s_cpwait: wait for cp port ack ----
317
        n.cpreq := '0';                   -- cpreq only for 1 cycle
318
 
319
        if (irb_selc or irb_seli) = '0' then    -- rbus cycle abort
320
          n.state := s_idle;              -- quit
321
        else
322
          irb_dout := CP_DOUT;
323
          irb_err  := CP_STAT.cmderr  or CP_STAT.cmdmerr;
324
          if CP_STAT.cmdack = '1' then       -- normal cycle end
325
            if r.doinc = '1' then
326
              n.addr := unsigned(r.addr) + 1;
327
            end if;
328
            if r.waitstep = '1' then
329
              irb_busy := '1';
330
              n.state := s_cpstep;
331
            else
332
              n.state := s_idle;
333
            end if;
334
          else
335
            irb_busy := '1';
336
          end if;
337
        end if;
338
 
339
      when s_cpstep =>                  -- s_cpstep: wait for cpustep done ---
340
        if irb_selc = '0' then            -- rbus cycle abort
341
          n.state := s_idle;                -- quit
342
        else
343
          if CP_STAT.cpustep = '0' then      -- cpustep done
344
            n.state := s_idle;
345
          else
346
            irb_busy := '1';
347
          end if;
348
        end if;
349
 
350
      when others => null;
351
    end case;
352
 
353
    icpaddr := cp_addr_init;
354
    icpaddr.addr      := r.addr;
355
    icpaddr.racc      := '0';
356
    icpaddr.be        := "11";
357
    icpaddr.ena_22bit := r.ena_22bit;
358
    icpaddr.ena_ubmap := r.ena_ubmap;
359
 
360
    if irb_seli = '1' then
361
      icpaddr.addr(15 downto 13)    := "111";
362
      icpaddr.addr(c_ibrb_ibf_base) := r.ibrbase;
363
      icpaddr.addr(5 downto 1)      := RB_MREQ.addr(4 downto 0);
364
      icpaddr.racc      := '1';
365
      icpaddr.be        := r.ibrbe;
366
      icpaddr.ena_22bit := '0';
367
      icpaddr.ena_ubmap := '0';
368
    end if;
369
 
370
    n.cpugo_1 := CP_STAT.cpugo;         -- delay cpugo 
371
    if CP_STAT.cpugo='0' and r.cpugo_1='1' then  -- cpugo 1 -> 0 transition ?
372
      irb_lam := '1';
373
    end if;
374
 
375
    N_REGS <= n;
376
 
377
    RB_SRES.ack  <= irb_ack;
378
    RB_SRES.err  <= irb_err;
379
    RB_SRES.busy <= irb_busy;
380
    RB_SRES.dout <= irb_dout;
381
 
382
    RB_STAT(0) <= CP_STAT.cpugo;
383
    RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left);
384
    RB_STAT(2) <= CP_STAT.cmderr  or CP_STAT.cmdmerr;
385
 
386 8 wfjm
    RB_LAM     <= irb_lam;
387 2 wfjm
 
388
    CPU_RESET  <= icpureset;
389
 
390
    CP_CNTL.req  <= r.cpreq;
391
    CP_CNTL.func <= r.cpfunc;
392
    CP_CNTL.rnum <= RB_MREQ.addr(2 downto 0);
393
 
394
    CP_ADDR <= icpaddr;
395
    CP_DIN  <= RB_MREQ.din;
396
 
397
  end process proc_next;
398
 
399
end syn;

powered by: WebSVN 2.1.0

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