DcacheToMmuType,
MmuToIcacheType
-# library ieee; use ieee.std_logic_1164.all;
-# use ieee.numeric_std.all;
-
-# library work; use work.common.all;
-
-
# -- Radix MMU
# -- Supports 4-level trees as in arch 3.0B, but not the
# -- two-step translation
# -- for guests under a hypervisor (i.e. there is no gRA -> hRA translation).
-# type state_t is
-# (IDLE,
-# DO_TLBIE,
-# TLB_WAIT,
-# PROC_TBL_READ,
-# PROC_TBL_WAIT,
-# SEGMENT_CHECK,
-# RADIX_LOOKUP,
-# RADIX_READ_WAIT,
-# RADIX_LOAD_TLB,
-# RADIX_FINISH
-# );
-
-# architecture behave of mmu is
-
@unique
class State(Enum):
IDLE = 0
RADIX_LOAD_TLB = 8
RADIX_FINISH = 9
-# type reg_stage_t is record
-# -- latched request from loadstore1
-# valid : std_ulogic;
-# iside : std_ulogic;
-# store : std_ulogic;
-# priv : std_ulogic;
-# addr : std_ulogic_vector(63 downto 0);
-# inval_all : std_ulogic;
-# -- config SPRs
-# prtbl : std_ulogic_vector(63 downto 0);
-# pid : std_ulogic_vector(31 downto 0);
-# -- internal state
-# state : state_t;
-# done : std_ulogic;
-# err : std_ulogic;
-# pgtbl0 : std_ulogic_vector(63 downto 0);
-# pt0_valid : std_ulogic;
-# pgtbl3 : std_ulogic_vector(63 downto 0);
-# pt3_valid : std_ulogic;
-# shift : unsigned(5 downto 0);
-# mask_size : unsigned(4 downto 0);
-# pgbase : std_ulogic_vector(55 downto 0);
-# pde : std_ulogic_vector(63 downto 0);
-# invalid : std_ulogic;
-# badtree : std_ulogic;
-# segerror : std_ulogic;
-# perm_err : std_ulogic;
-# rc_error : std_ulogic;
-# end record;
+
+# -- generate mask for extracting address fields for PTE address
+# -- generation
+# addrmaskgen: process(all)
+# generate mask for extracting address fields for PTE address
+# generation
+class AddrMaskGen(Elaboratable, MMU):
+ def __init__(self):
+# variable m : std_ulogic_vector(15 downto 0);
+ super().__init__()
+ self.msk = Signal(16)
+
+# begin
+ def elaborate(self, platform):
+ m = Module()
+
+ comb = m.d.comb
+ sync = m.d.sync
+
+ rst = ResetSignal()
+
+ msk = self.msk
+
+ r = self.r
+ mask = self.mask
+
+# -- mask_count has to be >= 5
+# m := x"001f";
+ # mask_count has to be >= 5
+ comb += mask.eq(Const(0x001F, 16)
+
+# for i in 5 to 15 loop
+ for i in range(5,16):
+# if i < to_integer(r.mask_size) then
+ with m.If(i < r.mask_size):
+# m(i) := '1';
+ comb += msk[i].eq(1)
+# end if;
+# end loop;
+# mask <= m;
+ comb += mask.eq(msk)
+# end process;
+
+# -- generate mask for extracting address bits to go in
+# -- TLB entry in order to support pages > 4kB
+# finalmaskgen: process(all)
+# generate mask for extracting address bits to go in
+# TLB entry in order to support pages > 4kB
+class FinalMaskGen(Elaboratable, MMU):
+ def __init__(self):
+# variable m : std_ulogic_vector(43 downto 0);
+ super().__init__()
+ self.msk = Signal(44)
+
+# begin
+ def elaborate(self, platform):
+ m = Module()
+
+ comb = m.d.comb
+ sync = m.d.sync
+
+ rst = ResetSignal()
+
+ mask = self.mask
+ r = self.r
+
+ msk = self.msk
+
+# for i in 0 to 43 loop
+ for i in range(44):
+# if i < to_integer(r.shift) then
+ with m.If(i < r.shift):
+# m(i) := '1';
+ comb += msk.eq(1)
+# end if;
+# end loop;
+# finalmask <= m;
+ comb += self.finalmask(mask)
+# end process;
class RegStage(RecordObject):
# two-step translation for guests under a hypervisor
# (i.e. there is no gRA -> hRA translation).
class MMU(Elaboratable):
-# entity mmu is
-# port (
-# clk : in std_ulogic;
-# rst : in std_ulogic;
-#
-# l_in : in Loadstore1ToMmuType;
-# l_out : out MmuToLoadstore1Type;
-#
-# d_out : out MmuToDcacheType;
-# d_in : in DcacheToMmuType;
-#
-# i_out : out MmuToIcacheType
-# );
-# end mmu;
def __init__(self):
self.l_in = LoadStore1ToMmuType()
self.l_out = MmuToLoadStore1Type()
self.d_in = DcacheToMmuType()
self.i_out = MmuToIcacheType()
-# signal addrsh : std_ulogic_vector(15 downto 0);
-# signal mask : std_ulogic_vector(15 downto 0);
-# signal finalmask : std_ulogic_vector(43 downto 0);
- self.addrsh = Signal(16)
- self.mask = Signal(16)
- self.finalmask = Signal(44)
-
-# signal r, rin : reg_stage_t;
- self.r = RegStage()
- self.rin = RegStage()
-
# begin
def elaborate(self, platform):
-# -- Multiplex internal SPR values back to loadstore1,
-# -- selected by l_in.sprn.
# Multiplex internal SPR values back to loadstore1,
# selected by l_in.sprn.
m = Module()
comb = m.d.comb
sync = m.d.sync
+ addrsh = Signal(16)
+ mask = Signal(16)
+ finalmask = Signal(44)
+
+ r = RegStage()
+ rin = RegStage()
+
l_in = self.l_in
l_out = self.l_out
d_out = self.d_out
d_in = self.d_in
i_out = self.i_out
- addrsh = self.addrsh
- mask = self.mask
- finalmask = self.finalmask
-
- r = self.r
- rin = self.rin
-
# l_out.sprval <= r.prtbl when l_in.sprn(9) = '1'
with m.If(l_in.sprn[9]):
comb += l_out.sprval.eq(r.prtbl)
# r <= rin;
sync += r.eq(rin)
-# end process;
-
-# -- generate mask for extracting address fields for PTE address
-# -- generation
-# addrmaskgen: process(all)
-# generate mask for extracting address fields for PTE address
-# generation
-class AddrMaskGen(Elaboratable, MMU):
- def __init__(self):
-# variable m : std_ulogic_vector(15 downto 0);
- super().__init__()
- self.msk = Signal(16)
-
-# begin
- def elaborate(self, platform):
- m = Module()
-
- comb = m.d.comb
- sync = m.d.sync
-
- rst = ResetSignal()
-
- msk = self.msk
-
- r = self.r
- mask = self.mask
-
-# -- mask_count has to be >= 5
-# m := x"001f";
- # mask_count has to be >= 5
- comb += mask.eq(Const(0x001F, 16)
-
-# for i in 5 to 15 loop
- for i in range(5,16):
-# if i < to_integer(r.mask_size) then
- with m.If(i < r.mask_size):
-# m(i) := '1';
- comb += msk[i].eq(1)
-# end if;
-# end loop;
-# mask <= m;
- comb += mask.eq(msk)
-# end process;
-
-# -- generate mask for extracting address bits to go in
-# -- TLB entry in order to support pages > 4kB
-# finalmaskgen: process(all)
-# generate mask for extracting address bits to go in
-# TLB entry in order to support pages > 4kB
-class FinalMaskGen(Elaboratable, MMU):
- def __init__(self):
-# variable m : std_ulogic_vector(43 downto 0);
- super().__init__()
- self.msk = Signal(44)
-
-# begin
- def elaborate(self, platform):
- m = Module()
-
- comb = m.d.comb
- sync = m.d.sync
-
- rst = ResetSignal()
-
- mask = self.mask
- r = self.r
-
- msk = self.msk
-
-# for i in 0 to 43 loop
- for i in range(44):
-# if i < to_integer(r.shift) then
- with m.If(i < r.shift):
-# m(i) := '1';
- comb += msk.eq(1)
-# end if;
-# end loop;
-# finalmask <= m;
- comb += self.finalmask(mask)
-# end process;
-
-# mmu_1: process(all)
-class MMU1(Elaboratable):
- def __init__(self):
-# variable v : reg_stage_t;
-# variable dcreq : std_ulogic;
-# variable tlb_load : std_ulogic;
-# variable itlb_load : std_ulogic;
-# variable tlbie_req : std_ulogic;
-# variable prtbl_rd : std_ulogic;
-# variable pt_valid : std_ulogic;
-# variable effpid : std_ulogic_vector(31 downto 0);
-# variable prtable_addr : std_ulogic_vector(63 downto 0);
-# variable rts : unsigned(5 downto 0);
-# variable mbits : unsigned(5 downto 0);
-# variable pgtable_addr : std_ulogic_vector(63 downto 0);
-# variable pte : std_ulogic_vector(63 downto 0);
-# variable tlb_data : std_ulogic_vector(63 downto 0);
-# variable nonzero : std_ulogic;
-# variable pgtbl : std_ulogic_vector(63 downto 0);
-# variable perm_ok : std_ulogic;
-# variable rc_ok : std_ulogic;
-# variable addr : std_ulogic_vector(63 downto 0);
-# variable data : std_ulogic_vector(63 downto 0);
- self.v = RegStage()
- self.dcrq = Signal()
- self.tlb_load = Signal()
- self.itlb_load = Signal()
- self.tlbie_req = Signal()
- self.prtbl_rd = Signal()
- self.pt_valid = Signal()
- self.effpid = Signal(32)
- self.prtable_addr = Signal(64)
- self.rts = Signal(6)
- self.mbits = Signal(6)
- self.pgtable_addr = Signal(64)
- self.pte = Signal(64)
- self.tlb_data = Signal(64)
- self.nonzero = Signal()
- self.pgtbl = Signal(64)
- self.perm_ok = Signal()
- self.rc_ok = Signal()
- self.addr = Signal(64)
- self.data = Signal(64)
-
-# begin
- def elaborate(self, platform):
-
- m = Module()
-
- comb = m.d.comb
- sync = m.d.sync
-
- l_in = self.l_in
- l_out = self.l_out
- d_out = self.d_out
- d_in = self.d_in
- i_out = self.i_out
- r = self.r
-
- v = self.v
- dcrq = self.dcrq
- tlb_load = self.tlb_load
- itlb_load = self.itlb_load
- tlbie_req = self.tlbie_req
- prtbl_rd = self.prtbl_rd
- pt_valid = self.pt_valid
- effpid = self.effpid
- prtable_addr = self.prtable_addr
- rts = self.rts
- mbits = self.mbits
- pgtable_addr = self.pgtable_addr
- pte = self.pte
- tlb_data = self.tlb_data
- nonzero = self.nonzero
- pgtbl = self.pgtbl
- perm_ok = self.perm_ok
- rc_ok = self.rc_ok
- addr = self.addr
- data = self.data
-
-# v := r;
-# v.valid := '0';
-# dcreq := '0';
-# v.done := '0';
-# v.err := '0';
-# v.invalid := '0';
-# v.badtree := '0';
-# v.segerror := '0';
-# v.perm_err := '0';
-# v.rc_error := '0';
-# tlb_load := '0';
-# itlb_load := '0';
-# tlbie_req := '0';
-# v.inval_all := '0';
-# prtbl_rd := '0';
+ v = RegStage()
+ dcrq = Signal()
+ tlb_load = Signal()
+ itlb_load = Signal()
+ tlbie_req = Signal()
+ prtbl_rd = Signal()
+ pt_valid = Signal()
+ effpid = Signal(32)
+ prtable_addr = Signal(64)
+ rts = Signal(6)
+ mbits = Signal(6)
+ pgtable_addr = Signal(64)
+ pte = Signal(64)
+ tlb_data = Signal(64)
+ nonzero = Signal()
+ pgtbl = Signal(64)
+ perm_ok = Signal()
+ rc_ok = Signal()
+ addr = Signal(64)
+ data = Signal(64)
comb += v.eq(r)
comb += v.valid.eq(0)