-- $Id: pdp11_mmu.vhd 677 2015-05-09 21:52:32Z mueller $
|
-- $Id: pdp11_mmu.vhd 677 2015-05-09 21:52:32Z mueller $
|
--
|
--
|
-- Copyright 2006-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2006-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
--
|
--
|
-- This program is free software; you may redistribute and/or modify it under
|
-- This program is free software; you may redistribute and/or modify it under
|
-- the terms of the GNU General Public License as published by the Free
|
-- the terms of the GNU General Public License as published by the Free
|
-- Software Foundation, either version 2, or at your option any later version.
|
-- Software Foundation, either version 2, or at your option any later version.
|
--
|
--
|
-- This program is distributed in the hope that it will be useful, but
|
-- This program is distributed in the hope that it will be useful, but
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- for complete details.
|
-- for complete details.
|
--
|
--
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- Module Name: pdp11_mmu - syn
|
-- Module Name: pdp11_mmu - syn
|
-- Description: pdp11: mmu - memory management unit
|
-- Description: pdp11: mmu - memory management unit
|
--
|
--
|
-- Dependencies: pdp11_mmu_sadr
|
-- Dependencies: pdp11_mmu_sadr
|
-- pdp11_mmu_ssr12
|
-- pdp11_mmu_ssr12
|
-- ibus/ib_sres_or_3
|
-- ibus/ib_sres_or_3
|
-- ibus/ib_sel
|
-- ibus/ib_sel
|
--
|
--
|
-- Test bench: tb/tb_pdp11_core (implicit)
|
-- Test bench: tb/tb_pdp11_core (implicit)
|
-- Target Devices: generic
|
-- Target Devices: generic
|
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
|
-- Tool versions: ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
-- 2011-11-18 427 1.4.2 now numeric_std clean
|
-- 2011-11-18 427 1.4.2 now numeric_std clean
|
-- 2010-10-23 335 1.4.1 use ib_sel
|
-- 2010-10-23 335 1.4.1 use ib_sel
|
-- 2010-10-17 333 1.4 use ibus V2 interface
|
-- 2010-10-17 333 1.4 use ibus V2 interface
|
-- 2010-06-20 307 1.3.7 rename cpacc to cacc in mmu_cntl_type
|
-- 2010-06-20 307 1.3.7 rename cpacc to cacc in mmu_cntl_type
|
-- 2009-05-30 220 1.3.6 final removal of snoopers (were already commented)
|
-- 2009-05-30 220 1.3.6 final removal of snoopers (were already commented)
|
-- 2009-05-09 213 1.3.5 BUGFIX: tie inst_compl permanentely '0'
|
-- 2009-05-09 213 1.3.5 BUGFIX: tie inst_compl permanentely '0'
|
-- BUGFIX: set ssr0 trap_mmu even when traps disabled
|
-- BUGFIX: set ssr0 trap_mmu even when traps disabled
|
-- 2008-08-22 161 1.3.4 rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_
|
-- 2008-08-22 161 1.3.4 rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_
|
-- 2008-04-27 139 1.3.3 allow ssr1/2 tracing even with mmu_ena=0
|
-- 2008-04-27 139 1.3.3 allow ssr1/2 tracing even with mmu_ena=0
|
-- 2008-04-25 138 1.3.2 add BRESET port, clear ssr0/3 with BRESET
|
-- 2008-04-25 138 1.3.2 add BRESET port, clear ssr0/3 with BRESET
|
-- 2008-03-02 121 1.3.1 remove snoopers
|
-- 2008-03-02 121 1.3.1 remove snoopers
|
-- 2008-02-24 119 1.3 return always mapped address in PADDRH; remove
|
-- 2008-02-24 119 1.3 return always mapped address in PADDRH; remove
|
-- cpacc handling; PADDR generation now on _vmbox
|
-- cpacc handling; PADDR generation now on _vmbox
|
-- 2008-01-05 110 1.2.1 rename _mmu_regs -> _mmu_sadr
|
-- 2008-01-05 110 1.2.1 rename _mmu_regs -> _mmu_sadr
|
-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
|
-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy)
|
-- 2008-01-01 109 1.2 use pdp11_mmu_regs (rather than _regset)
|
-- 2008-01-01 109 1.2 use pdp11_mmu_regs (rather than _regset)
|
-- 2007-12-31 108 1.1.1 remove SADR memory address mux (-> _mmu_regfile)
|
-- 2007-12-31 108 1.1.1 remove SADR memory address mux (-> _mmu_regfile)
|
-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now
|
-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now
|
-- 2007-06-14 56 1.0.1 Use slvtypes.all
|
-- 2007-06-14 56 1.0.1 Use slvtypes.all
|
-- 2007-05-12 26 1.0 Initial version
|
-- 2007-05-12 26 1.0 Initial version
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
use work.slvtypes.all;
|
use work.slvtypes.all;
|
use work.iblib.all;
|
use work.iblib.all;
|
use work.pdp11.all;
|
use work.pdp11.all;
|
|
|
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
|
|
entity pdp11_mmu is -- mmu - memory management unit
|
entity pdp11_mmu is -- mmu - memory management unit
|
port (
|
port (
|
CLK : in slbit; -- clock
|
CLK : in slbit; -- clock
|
CRESET : in slbit; -- cpu reset
|
CRESET : in slbit; -- cpu reset
|
BRESET : in slbit; -- bus reset
|
BRESET : in slbit; -- bus reset
|
CNTL : in mmu_cntl_type; -- control port
|
CNTL : in mmu_cntl_type; -- control port
|
VADDR : in slv16; -- virtual address
|
VADDR : in slv16; -- virtual address
|
MONI : in mmu_moni_type; -- monitor port
|
MONI : in mmu_moni_type; -- monitor port
|
STAT : out mmu_stat_type; -- status port
|
STAT : out mmu_stat_type; -- status port
|
PADDRH : out slv16; -- physical address (upper 16 bit)
|
PADDRH : out slv16; -- physical address (upper 16 bit)
|
IB_MREQ: in ib_mreq_type; -- ibus request
|
IB_MREQ: in ib_mreq_type; -- ibus request
|
IB_SRES: out ib_sres_type -- ibus response
|
IB_SRES: out ib_sres_type -- ibus response
|
);
|
);
|
end pdp11_mmu;
|
end pdp11_mmu;
|
|
|
architecture syn of pdp11_mmu is
|
architecture syn of pdp11_mmu is
|
|
|
constant ibaddr_ssr0 : slv16 := slv(to_unsigned(8#177572#,16));
|
constant ibaddr_ssr0 : slv16 := slv(to_unsigned(8#177572#,16));
|
constant ibaddr_ssr3 : slv16 := slv(to_unsigned(8#172516#,16));
|
constant ibaddr_ssr3 : slv16 := slv(to_unsigned(8#172516#,16));
|
|
|
constant ssr0_ibf_abo_nonres : integer := 15;
|
constant ssr0_ibf_abo_nonres : integer := 15;
|
constant ssr0_ibf_abo_length : integer := 14;
|
constant ssr0_ibf_abo_length : integer := 14;
|
constant ssr0_ibf_abo_rdonly : integer := 13;
|
constant ssr0_ibf_abo_rdonly : integer := 13;
|
constant ssr0_ibf_trap_mmu : integer := 12;
|
constant ssr0_ibf_trap_mmu : integer := 12;
|
constant ssr0_ibf_ena_trap : integer := 9;
|
constant ssr0_ibf_ena_trap : integer := 9;
|
constant ssr0_ibf_inst_compl : integer := 7;
|
constant ssr0_ibf_inst_compl : integer := 7;
|
subtype ssr0_ibf_seg_mode is integer range 6 downto 5;
|
subtype ssr0_ibf_seg_mode is integer range 6 downto 5;
|
constant ssr0_ibf_dspace : integer := 4;
|
constant ssr0_ibf_dspace : integer := 4;
|
subtype ssr0_ibf_seg_num is integer range 3 downto 1;
|
subtype ssr0_ibf_seg_num is integer range 3 downto 1;
|
constant ssr0_ibf_ena_mmu : integer := 0;
|
constant ssr0_ibf_ena_mmu : integer := 0;
|
|
|
constant ssr3_ibf_ena_ubmap : integer := 5;
|
constant ssr3_ibf_ena_ubmap : integer := 5;
|
constant ssr3_ibf_ena_22bit : integer := 4;
|
constant ssr3_ibf_ena_22bit : integer := 4;
|
constant ssr3_ibf_dspace_km : integer := 2;
|
constant ssr3_ibf_dspace_km : integer := 2;
|
constant ssr3_ibf_dspace_sm : integer := 1;
|
constant ssr3_ibf_dspace_sm : integer := 1;
|
constant ssr3_ibf_dspace_um : integer := 0;
|
constant ssr3_ibf_dspace_um : integer := 0;
|
|
|
signal IBSEL_SSR0 : slbit := '0'; -- ibus select SSR0
|
signal IBSEL_SSR0 : slbit := '0'; -- ibus select SSR0
|
signal IBSEL_SSR3 : slbit := '0'; -- ibus select SSR3
|
signal IBSEL_SSR3 : slbit := '0'; -- ibus select SSR3
|
|
|
signal R_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
|
signal R_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
|
signal N_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
|
signal N_SSR0 : mmu_ssr0_type := mmu_ssr0_init;
|
|
|
signal R_SSR3 : mmu_ssr3_type := mmu_ssr3_init;
|
signal R_SSR3 : mmu_ssr3_type := mmu_ssr3_init;
|
|
|
signal ASN : slv4 := "0000"; -- augmented segment number (1+3 bit)
|
signal ASN : slv4 := "0000"; -- augmented segment number (1+3 bit)
|
signal AIB_WE : slbit := '0'; -- update AIB
|
signal AIB_WE : slbit := '0'; -- update AIB
|
signal AIB_SETA : slbit := '0'; -- set A bit in access information bits
|
signal AIB_SETA : slbit := '0'; -- set A bit in access information bits
|
signal AIB_SETW : slbit := '0'; -- set W bit in access information bits
|
signal AIB_SETW : slbit := '0'; -- set W bit in access information bits
|
|
|
signal TRACE : slbit := '0'; -- enable tracing in ssr1/2
|
signal TRACE : slbit := '0'; -- enable tracing in ssr1/2
|
signal DSPACE : slbit := '0'; -- use dspace
|
signal DSPACE : slbit := '0'; -- use dspace
|
|
|
signal IB_SRES_SADR : ib_sres_type := ib_sres_init;
|
signal IB_SRES_SADR : ib_sres_type := ib_sres_init;
|
signal IB_SRES_SSR12 : ib_sres_type := ib_sres_init;
|
signal IB_SRES_SSR12 : ib_sres_type := ib_sres_init;
|
signal IB_SRES_SSR03 : ib_sres_type := ib_sres_init;
|
signal IB_SRES_SSR03 : ib_sres_type := ib_sres_init;
|
|
|
signal SARSDR : sarsdr_type := sarsdr_init;
|
signal SARSDR : sarsdr_type := sarsdr_init;
|
|
|
begin
|
begin
|
|
|
SADR : pdp11_mmu_sadr port map (
|
SADR : pdp11_mmu_sadr port map (
|
CLK => CLK,
|
CLK => CLK,
|
MODE => CNTL.mode,
|
MODE => CNTL.mode,
|
ASN => ASN,
|
ASN => ASN,
|
AIB_WE => AIB_WE,
|
AIB_WE => AIB_WE,
|
AIB_SETA => AIB_SETA,
|
AIB_SETA => AIB_SETA,
|
AIB_SETW => AIB_SETW,
|
AIB_SETW => AIB_SETW,
|
SARSDR => SARSDR,
|
SARSDR => SARSDR,
|
IB_MREQ => IB_MREQ,
|
IB_MREQ => IB_MREQ,
|
IB_SRES => IB_SRES_SADR);
|
IB_SRES => IB_SRES_SADR);
|
|
|
SSR12 : pdp11_mmu_ssr12 port map (
|
SSR12 : pdp11_mmu_ssr12 port map (
|
CLK => CLK,
|
CLK => CLK,
|
CRESET => CRESET,
|
CRESET => CRESET,
|
TRACE => TRACE,
|
TRACE => TRACE,
|
MONI => MONI,
|
MONI => MONI,
|
IB_MREQ => IB_MREQ,
|
IB_MREQ => IB_MREQ,
|
IB_SRES => IB_SRES_SSR12);
|
IB_SRES => IB_SRES_SSR12);
|
|
|
SRES_OR : ib_sres_or_3
|
SRES_OR : ib_sres_or_3
|
port map (
|
port map (
|
IB_SRES_1 => IB_SRES_SADR,
|
IB_SRES_1 => IB_SRES_SADR,
|
IB_SRES_2 => IB_SRES_SSR12,
|
IB_SRES_2 => IB_SRES_SSR12,
|
IB_SRES_3 => IB_SRES_SSR03,
|
IB_SRES_3 => IB_SRES_SSR03,
|
IB_SRES_OR => IB_SRES);
|
IB_SRES_OR => IB_SRES);
|
|
|
SEL_SSR0 : ib_sel
|
SEL_SSR0 : ib_sel
|
generic map (
|
generic map (
|
IB_ADDR => ibaddr_ssr0)
|
IB_ADDR => ibaddr_ssr0)
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
IB_MREQ => IB_MREQ,
|
IB_MREQ => IB_MREQ,
|
SEL => IBSEL_SSR0
|
SEL => IBSEL_SSR0
|
);
|
);
|
SEL_SSR3 : ib_sel
|
SEL_SSR3 : ib_sel
|
generic map (
|
generic map (
|
IB_ADDR => ibaddr_ssr3)
|
IB_ADDR => ibaddr_ssr3)
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
IB_MREQ => IB_MREQ,
|
IB_MREQ => IB_MREQ,
|
SEL => IBSEL_SSR3
|
SEL => IBSEL_SSR3
|
);
|
);
|
|
|
proc_ibres : process (IBSEL_SSR0, IBSEL_SSR3, IB_MREQ, R_SSR0, R_SSR3)
|
proc_ibres : process (IBSEL_SSR0, IBSEL_SSR3, IB_MREQ, R_SSR0, R_SSR3)
|
|
|
variable ssr0out : slv16 := (others=>'0');
|
variable ssr0out : slv16 := (others=>'0');
|
variable ssr3out : slv16 := (others=>'0');
|
variable ssr3out : slv16 := (others=>'0');
|
|
|
begin
|
begin
|
|
|
ssr0out := (others=>'0');
|
ssr0out := (others=>'0');
|
if IBSEL_SSR0 = '1' then
|
if IBSEL_SSR0 = '1' then
|
ssr0out(ssr0_ibf_abo_nonres) := R_SSR0.abo_nonres;
|
ssr0out(ssr0_ibf_abo_nonres) := R_SSR0.abo_nonres;
|
ssr0out(ssr0_ibf_abo_length) := R_SSR0.abo_length;
|
ssr0out(ssr0_ibf_abo_length) := R_SSR0.abo_length;
|
ssr0out(ssr0_ibf_abo_rdonly) := R_SSR0.abo_rdonly;
|
ssr0out(ssr0_ibf_abo_rdonly) := R_SSR0.abo_rdonly;
|
ssr0out(ssr0_ibf_trap_mmu) := R_SSR0.trap_mmu;
|
ssr0out(ssr0_ibf_trap_mmu) := R_SSR0.trap_mmu;
|
ssr0out(ssr0_ibf_ena_trap) := R_SSR0.ena_trap;
|
ssr0out(ssr0_ibf_ena_trap) := R_SSR0.ena_trap;
|
ssr0out(ssr0_ibf_inst_compl) := R_SSR0.inst_compl;
|
ssr0out(ssr0_ibf_inst_compl) := R_SSR0.inst_compl;
|
ssr0out(ssr0_ibf_seg_mode) := R_SSR0.seg_mode;
|
ssr0out(ssr0_ibf_seg_mode) := R_SSR0.seg_mode;
|
ssr0out(ssr0_ibf_dspace) := R_SSR0.dspace;
|
ssr0out(ssr0_ibf_dspace) := R_SSR0.dspace;
|
ssr0out(ssr0_ibf_seg_num) := R_SSR0.seg_num;
|
ssr0out(ssr0_ibf_seg_num) := R_SSR0.seg_num;
|
ssr0out(ssr0_ibf_ena_mmu) := R_SSR0.ena_mmu;
|
ssr0out(ssr0_ibf_ena_mmu) := R_SSR0.ena_mmu;
|
end if;
|
end if;
|
|
|
ssr3out := (others=>'0');
|
ssr3out := (others=>'0');
|
if IBSEL_SSR3 = '1' then
|
if IBSEL_SSR3 = '1' then
|
ssr3out(ssr3_ibf_ena_ubmap) := R_SSR3.ena_ubmap;
|
ssr3out(ssr3_ibf_ena_ubmap) := R_SSR3.ena_ubmap;
|
ssr3out(ssr3_ibf_ena_22bit) := R_SSR3.ena_22bit;
|
ssr3out(ssr3_ibf_ena_22bit) := R_SSR3.ena_22bit;
|
ssr3out(ssr3_ibf_dspace_km) := R_SSR3.dspace_km;
|
ssr3out(ssr3_ibf_dspace_km) := R_SSR3.dspace_km;
|
ssr3out(ssr3_ibf_dspace_sm) := R_SSR3.dspace_sm;
|
ssr3out(ssr3_ibf_dspace_sm) := R_SSR3.dspace_sm;
|
ssr3out(ssr3_ibf_dspace_um) := R_SSR3.dspace_um;
|
ssr3out(ssr3_ibf_dspace_um) := R_SSR3.dspace_um;
|
end if;
|
end if;
|
|
|
IB_SRES_SSR03.dout <= ssr0out or ssr3out;
|
IB_SRES_SSR03.dout <= ssr0out or ssr3out;
|
IB_SRES_SSR03.ack <= (IBSEL_SSR0 or IBSEL_SSR3) and
|
IB_SRES_SSR03.ack <= (IBSEL_SSR0 or IBSEL_SSR3) and
|
(IB_MREQ.re or IB_MREQ.we); -- ack all
|
(IB_MREQ.re or IB_MREQ.we); -- ack all
|
IB_SRES_SSR03.busy <= '0';
|
IB_SRES_SSR03.busy <= '0';
|
|
|
end process proc_ibres;
|
end process proc_ibres;
|
|
|
proc_ssr0 : process (CLK)
|
proc_ssr0 : process (CLK)
|
begin
|
begin
|
if rising_edge(CLK) then
|
if rising_edge(CLK) then
|
if BRESET = '1' then
|
if BRESET = '1' then
|
R_SSR0 <= mmu_ssr0_init;
|
R_SSR0 <= mmu_ssr0_init;
|
else
|
else
|
R_SSR0 <= N_SSR0;
|
R_SSR0 <= N_SSR0;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process proc_ssr0;
|
end process proc_ssr0;
|
|
|
proc_ssr3 : process (CLK)
|
proc_ssr3 : process (CLK)
|
begin
|
begin
|
if rising_edge(CLK) then
|
if rising_edge(CLK) then
|
if BRESET = '1' then
|
if BRESET = '1' then
|
R_SSR3 <= mmu_ssr3_init;
|
R_SSR3 <= mmu_ssr3_init;
|
elsif IBSEL_SSR3='1' and IB_MREQ.we='1' then
|
elsif IBSEL_SSR3='1' and IB_MREQ.we='1' then
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
R_SSR3.ena_ubmap <= IB_MREQ.din(ssr3_ibf_ena_ubmap);
|
R_SSR3.ena_ubmap <= IB_MREQ.din(ssr3_ibf_ena_ubmap);
|
R_SSR3.ena_22bit <= IB_MREQ.din(ssr3_ibf_ena_22bit);
|
R_SSR3.ena_22bit <= IB_MREQ.din(ssr3_ibf_ena_22bit);
|
R_SSR3.dspace_km <= IB_MREQ.din(ssr3_ibf_dspace_km);
|
R_SSR3.dspace_km <= IB_MREQ.din(ssr3_ibf_dspace_km);
|
R_SSR3.dspace_sm <= IB_MREQ.din(ssr3_ibf_dspace_sm);
|
R_SSR3.dspace_sm <= IB_MREQ.din(ssr3_ibf_dspace_sm);
|
R_SSR3.dspace_um <= IB_MREQ.din(ssr3_ibf_dspace_um);
|
R_SSR3.dspace_um <= IB_MREQ.din(ssr3_ibf_dspace_um);
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process proc_ssr3;
|
end process proc_ssr3;
|
|
|
proc_paddr : process (R_SSR0, R_SSR3, CNTL, SARSDR, VADDR)
|
proc_paddr : process (R_SSR0, R_SSR3, CNTL, SARSDR, VADDR)
|
|
|
variable ipaddrh : slv16 := (others=>'0');
|
variable ipaddrh : slv16 := (others=>'0');
|
variable dspace_ok : slbit := '0';
|
variable dspace_ok : slbit := '0';
|
variable dspace_en : slbit := '0';
|
variable dspace_en : slbit := '0';
|
variable asf : slv3 := (others=>'0'); -- va: active segment field
|
variable asf : slv3 := (others=>'0'); -- va: active segment field
|
variable bn : slv7 := (others=>'0'); -- va: block number
|
variable bn : slv7 := (others=>'0'); -- va: block number
|
variable iasn : slv4 := (others=>'0');-- augmented segment number
|
variable iasn : slv4 := (others=>'0');-- augmented segment number
|
|
|
begin
|
begin
|
|
|
asf := VADDR(15 downto 13);
|
asf := VADDR(15 downto 13);
|
bn := VADDR(12 downto 6);
|
bn := VADDR(12 downto 6);
|
|
|
dspace_en := '0';
|
dspace_en := '0';
|
case CNTL.mode is
|
case CNTL.mode is
|
when "00" => dspace_en := R_SSR3.dspace_km;
|
when "00" => dspace_en := R_SSR3.dspace_km;
|
when "01" => dspace_en := R_SSR3.dspace_sm;
|
when "01" => dspace_en := R_SSR3.dspace_sm;
|
when "11" => dspace_en := R_SSR3.dspace_um;
|
when "11" => dspace_en := R_SSR3.dspace_um;
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
dspace_ok := CNTL.dspace and dspace_en;
|
dspace_ok := CNTL.dspace and dspace_en;
|
|
|
iasn(3) := dspace_ok;
|
iasn(3) := dspace_ok;
|
iasn(2 downto 0) := asf;
|
iasn(2 downto 0) := asf;
|
|
|
ipaddrh := slv(unsigned("000000000"&bn) + unsigned(SARSDR.saf));
|
ipaddrh := slv(unsigned("000000000"&bn) + unsigned(SARSDR.saf));
|
|
|
DSPACE <= dspace_ok;
|
DSPACE <= dspace_ok;
|
ASN <= iasn;
|
ASN <= iasn;
|
PADDRH <= ipaddrh;
|
PADDRH <= ipaddrh;
|
|
|
end process proc_paddr;
|
end process proc_paddr;
|
|
|
proc_nssr0 : process (R_SSR0, R_SSR3, IB_MREQ, IBSEL_SSR0, DSPACE,
|
proc_nssr0 : process (R_SSR0, R_SSR3, IB_MREQ, IBSEL_SSR0, DSPACE,
|
CNTL, MONI, SARSDR, VADDR)
|
CNTL, MONI, SARSDR, VADDR)
|
|
|
variable nssr0 : mmu_ssr0_type := mmu_ssr0_init;
|
variable nssr0 : mmu_ssr0_type := mmu_ssr0_init;
|
variable asf : slv3 := (others=>'0');
|
variable asf : slv3 := (others=>'0');
|
variable bn : slv7 := (others=>'0');
|
variable bn : slv7 := (others=>'0');
|
variable abo_nonres : slbit := '0';
|
variable abo_nonres : slbit := '0';
|
variable abo_length : slbit := '0';
|
variable abo_length : slbit := '0';
|
variable abo_rdonly : slbit := '0';
|
variable abo_rdonly : slbit := '0';
|
variable ssr_freeze : slbit := '0';
|
variable ssr_freeze : slbit := '0';
|
variable doabort : slbit := '0';
|
variable doabort : slbit := '0';
|
variable dotrap : slbit := '0';
|
variable dotrap : slbit := '0';
|
variable dotrace : slbit := '0';
|
variable dotrace : slbit := '0';
|
|
|
begin
|
begin
|
|
|
nssr0 := R_SSR0;
|
nssr0 := R_SSR0;
|
|
|
AIB_WE <= '0';
|
AIB_WE <= '0';
|
AIB_SETA <= '0';
|
AIB_SETA <= '0';
|
AIB_SETW <= '0';
|
AIB_SETW <= '0';
|
|
|
ssr_freeze := R_SSR0.abo_nonres or R_SSR0.abo_length or R_SSR0.abo_rdonly;
|
ssr_freeze := R_SSR0.abo_nonres or R_SSR0.abo_length or R_SSR0.abo_rdonly;
|
dotrace := not(CNTL.cacc or ssr_freeze);
|
dotrace := not(CNTL.cacc or ssr_freeze);
|
|
|
asf := VADDR(15 downto 13);
|
asf := VADDR(15 downto 13);
|
bn := VADDR(12 downto 6);
|
bn := VADDR(12 downto 6);
|
|
|
abo_nonres := '0';
|
abo_nonres := '0';
|
abo_length := '0';
|
abo_length := '0';
|
abo_rdonly := '0';
|
abo_rdonly := '0';
|
doabort := '0';
|
doabort := '0';
|
dotrap := '0';
|
dotrap := '0';
|
|
|
if SARSDR.ed = '0' then -- ed=0: upward expansion
|
if SARSDR.ed = '0' then -- ed=0: upward expansion
|
if unsigned(bn) > unsigned(SARSDR.slf) then
|
if unsigned(bn) > unsigned(SARSDR.slf) then
|
abo_length := '1';
|
abo_length := '1';
|
end if;
|
end if;
|
else -- ed=0: downward expansion
|
else -- ed=0: downward expansion
|
if unsigned(bn) < unsigned(SARSDR.slf) then
|
if unsigned(bn) < unsigned(SARSDR.slf) then
|
abo_length := '1';
|
abo_length := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
case SARSDR.acf is -- evaluate accecc control field
|
case SARSDR.acf is -- evaluate accecc control field
|
|
|
when "000" => -- segment non-resident
|
when "000" => -- segment non-resident
|
abo_nonres := '1';
|
abo_nonres := '1';
|
|
|
when "001" => -- read-only; trap on read
|
when "001" => -- read-only; trap on read
|
if CNTL.wacc='1' or CNTL.macc='1' then
|
if CNTL.wacc='1' or CNTL.macc='1' then
|
abo_rdonly := '1';
|
abo_rdonly := '1';
|
end if;
|
end if;
|
dotrap := '1';
|
dotrap := '1';
|
|
|
when "010" => -- read-only
|
when "010" => -- read-only
|
if CNTL.wacc='1' or CNTL.macc='1' then
|
if CNTL.wacc='1' or CNTL.macc='1' then
|
abo_rdonly := '1';
|
abo_rdonly := '1';
|
end if;
|
end if;
|
|
|
when "100" => -- read/write; trap on read&write
|
when "100" => -- read/write; trap on read&write
|
dotrap := '1';
|
dotrap := '1';
|
|
|
when "101" => -- read/write; trap on write
|
when "101" => -- read/write; trap on write
|
dotrap := CNTL.wacc or CNTL.macc;
|
dotrap := CNTL.wacc or CNTL.macc;
|
|
|
when "110" => null; -- read/write;
|
when "110" => null; -- read/write;
|
|
|
when others => -- unused codes: abort access
|
when others => -- unused codes: abort access
|
abo_nonres := '1';
|
abo_nonres := '1';
|
end case;
|
end case;
|
|
|
if IBSEL_SSR0='1' and IB_MREQ.we='1' then
|
if IBSEL_SSR0='1' and IB_MREQ.we='1' then
|
|
|
if IB_MREQ.be1 = '1' then
|
if IB_MREQ.be1 = '1' then
|
nssr0.abo_nonres := IB_MREQ.din(ssr0_ibf_abo_nonres);
|
nssr0.abo_nonres := IB_MREQ.din(ssr0_ibf_abo_nonres);
|
nssr0.abo_length := IB_MREQ.din(ssr0_ibf_abo_length);
|
nssr0.abo_length := IB_MREQ.din(ssr0_ibf_abo_length);
|
nssr0.abo_rdonly := IB_MREQ.din(ssr0_ibf_abo_rdonly);
|
nssr0.abo_rdonly := IB_MREQ.din(ssr0_ibf_abo_rdonly);
|
nssr0.trap_mmu := IB_MREQ.din(ssr0_ibf_trap_mmu);
|
nssr0.trap_mmu := IB_MREQ.din(ssr0_ibf_trap_mmu);
|
nssr0.ena_trap := IB_MREQ.din(ssr0_ibf_ena_trap);
|
nssr0.ena_trap := IB_MREQ.din(ssr0_ibf_ena_trap);
|
end if;
|
end if;
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
nssr0.ena_mmu := IB_MREQ.din(ssr0_ibf_ena_mmu);
|
nssr0.ena_mmu := IB_MREQ.din(ssr0_ibf_ena_mmu);
|
end if;
|
end if;
|
|
|
elsif nssr0.ena_mmu='1' and CNTL.cacc='0' then
|
elsif nssr0.ena_mmu='1' and CNTL.cacc='0' then
|
|
|
if dotrace = '1' then
|
if dotrace = '1' then
|
if MONI.istart = '1' then
|
if MONI.istart = '1' then
|
nssr0.inst_compl := '0';
|
nssr0.inst_compl := '0';
|
elsif MONI.idone = '1' then
|
elsif MONI.idone = '1' then
|
nssr0.inst_compl := '0'; -- disable instr.compl logic
|
nssr0.inst_compl := '0'; -- disable instr.compl logic
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if CNTL.req = '1' then
|
if CNTL.req = '1' then
|
AIB_WE <= '1';
|
AIB_WE <= '1';
|
if ssr_freeze = '0' then
|
if ssr_freeze = '0' then
|
nssr0.abo_nonres := abo_nonres;
|
nssr0.abo_nonres := abo_nonres;
|
nssr0.abo_length := abo_length;
|
nssr0.abo_length := abo_length;
|
nssr0.abo_rdonly := abo_rdonly;
|
nssr0.abo_rdonly := abo_rdonly;
|
end if;
|
end if;
|
doabort := abo_nonres or abo_length or abo_rdonly;
|
doabort := abo_nonres or abo_length or abo_rdonly;
|
|
|
if doabort = '0' then
|
if doabort = '0' then
|
AIB_SETA <= '1';
|
AIB_SETA <= '1';
|
AIB_SETW <= CNTL.wacc or CNTL.macc;
|
AIB_SETW <= CNTL.wacc or CNTL.macc;
|
end if;
|
end if;
|
|
|
if ssr_freeze = '0' then
|
if ssr_freeze = '0' then
|
nssr0.dspace := DSPACE;
|
nssr0.dspace := DSPACE;
|
nssr0.seg_num := asf;
|
nssr0.seg_num := asf;
|
nssr0.seg_mode := CNTL.mode;
|
nssr0.seg_mode := CNTL.mode;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if CNTL.req='1' and R_SSR0.ena_mmu='1' and CNTL.cacc='0' and
|
if CNTL.req='1' and R_SSR0.ena_mmu='1' and CNTL.cacc='0' and
|
dotrap='1' then
|
dotrap='1' then
|
nssr0.trap_mmu := '1';
|
nssr0.trap_mmu := '1';
|
end if;
|
end if;
|
|
|
nssr0.trace_prev := dotrace;
|
nssr0.trace_prev := dotrace;
|
|
|
if MONI.trace_prev = '0' then
|
if MONI.trace_prev = '0' then
|
TRACE <= dotrace;
|
TRACE <= dotrace;
|
else
|
else
|
TRACE <= R_SSR0.trace_prev;
|
TRACE <= R_SSR0.trace_prev;
|
end if;
|
end if;
|
|
|
N_SSR0 <= nssr0;
|
N_SSR0 <= nssr0;
|
|
|
if R_SSR0.ena_mmu='1' and CNTL.cacc='0' then
|
if R_SSR0.ena_mmu='1' and CNTL.cacc='0' then
|
STAT.vaok <= not doabort;
|
STAT.vaok <= not doabort;
|
else
|
else
|
STAT.vaok <= '1';
|
STAT.vaok <= '1';
|
end if;
|
end if;
|
|
|
if R_SSR0.ena_mmu='1' and CNTL.cacc='0' and doabort='0' and
|
if R_SSR0.ena_mmu='1' and CNTL.cacc='0' and doabort='0' and
|
R_SSR0.ena_trap='1' and R_SSR0.trap_mmu='0' and dotrap='1' then
|
R_SSR0.ena_trap='1' and R_SSR0.trap_mmu='0' and dotrap='1' then
|
STAT.trap <= '1';
|
STAT.trap <= '1';
|
else
|
else
|
STAT.trap <= '0';
|
STAT.trap <= '0';
|
end if;
|
end if;
|
|
|
STAT.ena_mmu <= R_SSR0.ena_mmu;
|
STAT.ena_mmu <= R_SSR0.ena_mmu;
|
STAT.ena_22bit <= R_SSR3.ena_22bit;
|
STAT.ena_22bit <= R_SSR3.ena_22bit;
|
STAT.ena_ubmap <= R_SSR3.ena_ubmap;
|
STAT.ena_ubmap <= R_SSR3.ena_ubmap;
|
|
|
end process proc_nssr0;
|
end process proc_nssr0;
|
|
|
end syn;
|
end syn;
|
|
|