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