w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
pdp11_mmu_padr.vhd
Go to the documentation of this file.
1-- $Id: pdp11_mmu_padr.vhd 1279 2022-08-14 08:02:21Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: pdp11_mmu_sadr - syn
7-- Description: pdp11: mmu PAR/PDR register set
8--
9-- Dependencies: memlib/ram_1swar_gen
10--
11-- Test bench: tb/tb_pdp11_core (implicit)
12-- Target Devices: generic
13-- Tool versions: ise 8.2-14.7; viv 2014.4-2022.1; ghdl 0.18-2.0.0
14--
15-- Revision History:
16-- Date Rev Version Comment
17-- 2022-08-13 1279 1.3.4 ssr->mmr rename
18-- 2011-11-18 427 1.3.3 now numeric_std clean
19-- 2010-12-30 351 1.3.2 BUGFIX: fix sensitivity list of proc_eaddr
20-- 2010-10-23 335 1.3.1 change proc_eaddr logic, shorten logic path
21-- 2010-10-17 333 1.3 use ibus V2 interface
22-- 2008-08-22 161 1.2.2 rename ubf_ -> ibf_; use iblib
23-- 2008-01-05 110 1.2.1 rename _mmu_regs -> _mmu_sadr
24-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
25-- 2008-01-01 109 1.2 renamed from _mmu_regfile.
26-- redesign of _mmu register file, use one large dram.
27-- logic from _mmu_regfile, interface from _mmu_regset
28-- 2007-12-30 108 1.1.1 use ubf_byte[01]; move SADR memory address mux here
29-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now
30-- 2007-06-14 56 1.0.1 Use slvtypes.all
31-- 2007-05-12 26 1.0 Initial version
32------------------------------------------------------------------------------
33
34library ieee;
35use ieee.std_logic_1164.all;
36use ieee.numeric_std.all;
37
38use work.slvtypes.all;
39use work.memlib.all;
40use work.iblib.all;
41use work.pdp11.all;
42
43-- ----------------------------------------------------------------------------
44
45entity pdp11_mmu_padr is -- mmu PAR/PDR register set
46 port (
47 CLK : in slbit; -- clock
48 MODE : in slv2; -- mode
49 APN : in slv4; -- augmented page number (1+3 bit)
50 AIB_WE : in slbit; -- update AIB
51 AIB_SETA : in slbit; -- set access AIB
52 AIB_SETW : in slbit; -- set write AIB
53 PARPDR : out parpdr_type; -- combined PAR/PDR
54 IB_MREQ : in ib_mreq_type; -- ibus request
55 IB_SRES : out ib_sres_type -- ibus response
56 );
58
59architecture syn of pdp11_mmu_padr is
60
61 -- bit 1 111 1
62 -- bit 5 432 109 876 543 210
63 --
64 -- kmdr 172300 -> 1 111 010 011 000 000
65 -- kmar 172340 -> 1 111 010 011 100 000
66 -- smdr 172200 -> 1 111 010 010 000 000
67 -- smar 172240 -> 1 111 010 010 100 000
68 -- umdr 177600 -> 1 111 111 110 000 000
69 -- umar 177640 -> 1 111 111 110 100 000
70 --
71 -- mode => (addr(8), not addr(6)) [Note: km "00" sm "01" um "11"]
72
73 constant ibaddr_kmdar : slv16 := slv(to_unsigned(8#172300#,16));
74 constant ibaddr_smdar : slv16 := slv(to_unsigned(8#172200#,16));
75 constant ibaddr_umdar : slv16 := slv(to_unsigned(8#177600#,16));
76
77 subtype pdr_ibf_plf is integer range 14 downto 8;
78 subtype pdr_ibf_aib is integer range 7 downto 6;
79 subtype pdr_ibf_acf is integer range 3 downto 0;
80
81 signal PADR_ADDR : slv6 := (others=>'0'); -- address (from mmu or ibus)
82
83 signal PAR_HIGH_WE : slbit := '0'; -- write enables
84 signal PAR_LOW_WE : slbit := '0'; -- ...
85 signal PDR_PLF_WE : slbit := '0'; -- ...
86 signal PDR_AIB_WE : slbit := '0'; -- ...
87 signal PDR_LOW_WE : slbit := '0'; -- ...
88
89 signal R_IBSEL_DR : slbit := '0'; -- DR's selected from ibus
90 signal R_IBSEL_AR : slbit := '0'; -- AR's selected from ibus
91
92 signal PAF : slv16 := (others=>'0'); -- current PAF
93 signal PLF : slv7 := (others=>'0'); -- current PLF
94 signal AIB : slv2 := "00"; -- current AIB flags
95 signal N_AIB : slv2 := "00"; -- next AIB flags
96 signal ED_ACF : slv4 := "0000"; -- current ED & ACF
97
98begin
99
100 PAR_HIGH : ram_1swar_gen
101 generic map (
102 AWIDTH => 6,
103 DWIDTH => 8)
104 port map (
105 CLK => CLK,
106 WE => PAR_HIGH_WE,
107 ADDR => PADR_ADDR,
108 DI => IB_MREQ.din(ibf_byte1),
109 DO => PAF(ibf_byte1));
110
111 PAR_LOW : ram_1swar_gen
112 generic map (
113 AWIDTH => 6,
114 DWIDTH => 8)
115 port map (
116 CLK => CLK,
117 WE => PAR_LOW_WE,
118 ADDR => PADR_ADDR,
119 DI => IB_MREQ.din(ibf_byte0),
120 DO => PAF(ibf_byte0));
121
122 PDR_PLF : ram_1swar_gen
123 generic map (
124 AWIDTH => 6,
125 DWIDTH => 7)
126 port map (
127 CLK => CLK,
128 WE => PDR_PLF_WE,
129 ADDR => PADR_ADDR,
130 DI => IB_MREQ.din(pdr_ibf_plf),
131 DO => PLF);
132
133 PDR_AIB : ram_1swar_gen
134 generic map (
135 AWIDTH => 6,
136 DWIDTH => 2)
137 port map (
138 CLK => CLK,
139 WE => PDR_AIB_WE,
140 ADDR => PADR_ADDR,
141 DI => N_AIB,
142 DO => AIB);
143
144 PDR_LOW : ram_1swar_gen
145 generic map (
146 AWIDTH => 6,
147 DWIDTH => 4)
148 port map (
149 CLK => CLK,
150 WE => PDR_LOW_WE,
151 ADDR => PADR_ADDR,
152 DI => IB_MREQ.din(pdr_ibf_acf),
154
155 -- determine IBSEL's and the address for accessing the PADR's
156
157 proc_ibsel: process (CLK)
158 variable ibsel_dr : slbit := '0';
159 variable ibsel_ar : slbit := '0';
160 begin
161 if rising_edge(CLK) then
162 ibsel_dr := '0';
163 ibsel_ar := '0';
164 if IB_MREQ.aval = '1' then
165 if IB_MREQ.addr(12 downto 6)=ibaddr_kmdar(12 downto 6) or
166 IB_MREQ.addr(12 downto 6)=ibaddr_smdar(12 downto 6) or
167 IB_MREQ.addr(12 downto 6)=ibaddr_umdar(12 downto 6) then
168 if IB_MREQ.addr(5) = '0' then
169 ibsel_dr := '1';
170 else
171 ibsel_ar := '1';
172 end if;
173 end if;
174 end if;
175 R_IBSEL_DR <= ibsel_dr;
176 R_IBSEL_AR <= ibsel_ar;
177 end if;
178 end process proc_ibsel;
179
180 proc_ibres : process (R_IBSEL_DR, R_IBSEL_AR, IB_MREQ, PAF, PLF, AIB, ED_ACF)
181 variable parout : slv16 := (others=>'0'); -- IB par out
182 variable pdrout : slv16 := (others=>'0'); -- IB pdr out
183 begin
184
185 parout := (others=>'0');
186 if R_IBSEL_AR = '1' then
187 parout := PAF;
188 end if;
189
190 pdrout := (others=>'0');
191 if R_IBSEL_DR = '1' then
192 pdrout(pdr_ibf_plf) := PLF;
193 pdrout(pdr_ibf_aib) := AIB;
194 pdrout(pdr_ibf_acf) := ED_ACF;
195 end if;
196
197 IB_SRES.dout <= parout or pdrout;
198 IB_SRES.ack <= (R_IBSEL_DR or R_IBSEL_AR) and
199 (IB_MREQ.re or IB_MREQ.we); -- ack all
200 IB_SRES.busy <= '0';
201
202 end process proc_ibres;
203
204 -- the eaddr select should be done as early as possible, it is in the
205 -- mmu paadr logic path. Currently it's derived from 4 flops. If that's
206 -- to slow just use IB_MREQ.we or IB_MREQ.we, that should be sufficient
207 -- and reduce the eaddr mux to a 4-input LUT. Last resort is a 2 cycle ibus
208 -- access with a state flop marking the 2nd cycle of a re/we transaction.
209
210 proc_eaddr: process (IB_MREQ, MODE, APN, R_IBSEL_DR, R_IBSEL_AR)
211 variable eaddr : slv6 := (others=>'0');
212 variable idr : slbit := '0';
213 variable iar : slbit := '0';
214 begin
215
216 eaddr := MODE & APN;
217
218 if (R_IBSEL_DR='1' or R_IBSEL_AR='1') and
219 (IB_MREQ.re='1' or IB_MREQ.we='1') then
220 eaddr(5) := IB_MREQ.addr(8);
221 eaddr(4) := not IB_MREQ.addr(6);
222 eaddr(3 downto 0) := IB_MREQ.addr(4 downto 1);
223 end if;
224
225 PADR_ADDR <= eaddr;
226
227 end process proc_eaddr;
228
229 proc_comb : process (R_IBSEL_AR, R_IBSEL_DR, IB_MREQ, AIB_WE,
231 PAF, PLF, AIB, ED_ACF)
232 begin
233
234 N_AIB <= "00";
235 PAR_HIGH_WE <= '0';
236 PAR_LOW_WE <= '0';
237 PDR_PLF_WE <= '0';
238 PDR_AIB_WE <= '0';
239 PDR_LOW_WE <= '0';
240
241 if IB_MREQ.we = '1' then
242 if R_IBSEL_AR = '1' then
243 if IB_MREQ.be1 = '1' then
244 PAR_HIGH_WE <= '1';
245 end if;
246 if IB_MREQ.be0 = '1' then
247 PAR_LOW_WE <= '1';
248 end if;
249 end if;
250
251 if R_IBSEL_DR = '1' then
252 if IB_MREQ.be1 = '1' then
253 PDR_PLF_WE <= '1';
254 end if;
255 if IB_MREQ.be0 = '1' then
256 PDR_LOW_WE <= '1';
257 end if;
258 end if;
259
260 if (R_IBSEL_AR or R_IBSEL_DR)='1' then
261 N_AIB <= "00";
262 PDR_AIB_WE <= '1';
263 end if;
264 end if;
265
266 if AIB_WE = '1' then
267 N_AIB(0) <= AIB(0) or AIB_SETW;
268 N_AIB(1) <= AIB(1) or AIB_SETA;
269 PDR_AIB_WE <= '1';
270 end if;
271
272 PARPDR.paf <= PAF;
273 PARPDR.plf <= PLF;
274 PARPDR.ed <= ED_ACF(3);
275 PARPDR.acf <= ED_ACF(2 downto 0);
276
277 end process proc_comb;
278
279end syn;
Definition: iblib.vhd:33
slv16 := slv( to_unsigned( 8#172200#, 16) ) ibaddr_smdar
slbit := '0' PDR_PLF_WE
slbit := '0' PDR_AIB_WE
slv16 := slv( to_unsigned( 8#177600#, 16) ) ibaddr_umdar
slv6 :=( others => '0') PADR_ADDR
slv16 := slv( to_unsigned( 8#172300#, 16) ) ibaddr_kmdar
slv16 :=( others => '0') PAF
slv4 := "0000" ED_ACF
slbit := '0' R_IBSEL_AR
integer range 14 downto 8 pdr_ibf_plf
slbit := '0' PAR_HIGH_WE
slv2 := "00" N_AIB
slbit := '0' PDR_LOW_WE
slbit := '0' PAR_LOW_WE
integer range 7 downto 6 pdr_ibf_aib
slbit := '0' R_IBSEL_DR
slv7 :=( others => '0') PLF
integer range 3 downto 0 pdr_ibf_acf
in AIB_WE slbit
in IB_MREQ ib_mreq_type
out IB_SRES ib_sres_type
in AIB_SETW slbit
out PARPDR parpdr_type
in AIB_SETA slbit
Definition: pdp11.vhd:123
in ADDR slv( AWIDTH- 1 downto 0)
out DO slv( DWIDTH- 1 downto 0)
AWIDTH positive := 4
in DI slv( DWIDTH- 1 downto 0)
in CLK slbit
in WE slbit
DWIDTH positive := 16
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 6 downto 0) slv7
Definition: slvtypes.vhd:39
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 5 downto 0) slv6
Definition: slvtypes.vhd:38
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31