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

Subversion Repositories w11

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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