From: Daniel Benusovich Date: Sat, 23 Feb 2019 18:41:55 +0000 (-0800) Subject: Moving all source scripts X-Git-Tag: div_pipeline~2376 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=06f80b178b7f09cd276e84f2d7abe9dbd0948282;p=soc.git Moving all source scripts --- diff --git a/TLB/CacheWalker.py b/TLB/CacheWalker.py deleted file mode 100644 index d024067e..00000000 --- a/TLB/CacheWalker.py +++ /dev/null @@ -1,44 +0,0 @@ -from nmigen import Memory, Module, Signal -from nmigen.cli import main -from math import log - -# The purpose of this module is to search a memory block given an -# associativity. -# This module will attempt to find a matching entry when given an address -# and perform permission validation if successful. -# -# Arguments: -# data_size: (bit count) The size of the data words being processed -# assoc: (int) The associativity of the memory to be parsed -# mem: (nmigen.Memory) The memory to be parsed -# -# Return: -# 1. An entry was found -> Return PTE, set hit HIGH, set valid HIGH -# 2. An entry was NOT found -> set hit LOW, set valid HIGH -# 3. A permission fault occurs -> set hit LOW, set valid LOW -class CacheWalker(): - def __init__(self, data_size, assoc, mem): - # Parameter parsing - self.assoc = assoc # Assciativity of the cache - - self.read_port = mem.read_port - self.write_port = mem.write_port - - if (mem_size % assoc != 0): - print("Cache Walker: Memory cannot be distributed between sets") - - self.set_count = mem.depth / assoc # Number of sets in memory - self.set_bit_count = log(set_count, 2) # Bit count for sets - # Ensure set_bit_count is fully represented - if(set_count % 2 != 0): - set_bit_count += 1 - - self.assoc_bits = Signal(set_bit_count) # Bits for associativity - - # Inputs - self.vma = Signal(36) # Virtual Memory Address (VMA) - - # Output - self.hit = Signal(1) # Denotes if the VMA had a mapped PTE - self.pte = Signal(64) # PTE that was mapped to by the VMA - self.valid = Signal(1) # Denotes if the permissions are correct \ No newline at end of file diff --git a/TLB/PermissionValidator.py b/TLB/PermissionValidator.py deleted file mode 100644 index 7cc12d93..00000000 --- a/TLB/PermissionValidator.py +++ /dev/null @@ -1,61 +0,0 @@ -from nmigen import Signal -from nmigen.cli import main - -# The purpose of this Module is to check the Permissions of a given PTE -# against the requested access permissions. -# This module will either validate (by setting the valid bit HIGH) the request -# or find a permission fault and invalidate (by setting the valid bit LOW) -# the request -# -# Arguments: -# data_size: (bit count) The size of the data words being processed -# -# Return: -# 1. Data is valid -> valid is HIGH -# 2. Data is not valid -> valid is LOW -class PermissionValidator(): - def __init__(self, data_size): - # Input - self.data = Signal(data_size); - self.xwr = Signal(3) # Execute, Write, Read - self.super = Signal(1) # Supervisor Mode - self.super_access = Signal(1) # Supervisor Access - self.asid = Signal(15) # Address Space IDentifier (ASID) - - # Output - self.valid = Signal(1) # Denotes if the permissions are correct - - def elaborate(self, platform): - m = Module() - m.d.comb += [ - # Check if ASID matches OR entry is global - If(data[64:78] == self.asid or data[5] == 1, - # Check Execute, Write, Read (XWR) Permissions - If(data[3] == self.xwr[2] and data[2] == self.xwr[1] \ - and data[1] == self.xwr[0], - # Check if supervisor - If(self.super == 1, - # Check if entry is in user mode - # Check if supervisor has access - If(data[4] == 0, - self.valid.eq(1) - ).Elif(self.super_access == 1, - self.valid.eq(1) - ).Else( - self.valid.eq(0) - ) - ).Else( - # Check if entry is in user mode - If(data[4] == 1, - self.valid.eq(1) - ).Else( - self.valid.eq(0) - ) - ) - ).Else( - self.valid.eq(0) - ) - ).Else( - self.valid.eq(0) - ) - ] diff --git a/TLB/TLB.py b/TLB/TLB.py deleted file mode 100644 index b11e49e3..00000000 --- a/TLB/TLB.py +++ /dev/null @@ -1,72 +0,0 @@ -from nmigen import Memory, Module, Signal -from nmigen.cli import main - -from PermissionValidator import PermissionValidator - -# The expected form of the data is -# Item (Bits) -# Tag (N - 79) / ASID (78 - 64) / PTE (63 - 0) - -class TLB(): - def __init__(self): - # Inputs - self.super = Signal(1) # Supervisor Mode - self.super_access = Signal(1) # Supervisor Access - self.command = Signal(2) # 00=None, 01=Search, 10=Write PTE, 11=Reset - self.xwr = Signal(3) # Execute, Write, Read - self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64 - self.asid = Signal(15) # Address Space IDentifier (ASID) - self.vma = Signal(36) # Virtual Memory Address (VMA) - self.pte_in = Signal(64) # To be saved Page Table Entry (PTE) - - # Outputs - self.hit = Signal(1) # Denotes if the VMA had a mapped PTE - self.valid = Signal(1) # Denotes if the permissions are correct - self.pteOut = Signal(64) # PTE that was mapped to by the VMA - - # Cam simulations - mem_l1 = Memory(113, 32) # L1 TLB cache - read_port_l1 = mem_l1.read_port - write_port_l1 = mem_l1.write_port - - mem_l2 = Memory(113, 128) # L2 TLB cache - read_port_l2 = mem_l2.read_port - write_port_l2 = mem_l2.write_port - - def elaborate(self, platform): - m = Module() - m.d.submodules.perm_valid = perm_valid = PermissionValidator(113) - m.d.sync += [ - Case(self.command, { - # Search for PTE - 1: [ - # Check first entry in set - # TODO make module? - read_port_l1.addr.eq(vma[0,2]), - If(read_port_l1.data[0] == 1, - perm_valid.data.eq(read_port_l1.data), - perm_valid.xwr.eq(self.xwr), - perm_valid.super.eq(self.super), - perm_valid.super_access.eq(self.super_access), - perm_valid.asid.eq(self.asid), - self.valid,eq(perm_valid.valid) - ), - If(self.valid == 0, - read_port_l1.addr.eq(vma[0,2] + 1), - If(read_port_l1.data[0] == 1, - perm_valid.data.eq(read_port_l1.data), - perm_valid.xwr.eq(self.xwr), - perm_valid.super.eq(self.super), - perm_valid.super_access.eq(self.super_access), - perm_valid.asid.eq(self.asid), - self.valid,eq(perm_valid.valid) - ) - ) - ] - }) - ] - return m - -thing = TLB() -print("Gottem") - diff --git a/TLB/src/CacheWalker.py b/TLB/src/CacheWalker.py new file mode 100644 index 00000000..d024067e --- /dev/null +++ b/TLB/src/CacheWalker.py @@ -0,0 +1,44 @@ +from nmigen import Memory, Module, Signal +from nmigen.cli import main +from math import log + +# The purpose of this module is to search a memory block given an +# associativity. +# This module will attempt to find a matching entry when given an address +# and perform permission validation if successful. +# +# Arguments: +# data_size: (bit count) The size of the data words being processed +# assoc: (int) The associativity of the memory to be parsed +# mem: (nmigen.Memory) The memory to be parsed +# +# Return: +# 1. An entry was found -> Return PTE, set hit HIGH, set valid HIGH +# 2. An entry was NOT found -> set hit LOW, set valid HIGH +# 3. A permission fault occurs -> set hit LOW, set valid LOW +class CacheWalker(): + def __init__(self, data_size, assoc, mem): + # Parameter parsing + self.assoc = assoc # Assciativity of the cache + + self.read_port = mem.read_port + self.write_port = mem.write_port + + if (mem_size % assoc != 0): + print("Cache Walker: Memory cannot be distributed between sets") + + self.set_count = mem.depth / assoc # Number of sets in memory + self.set_bit_count = log(set_count, 2) # Bit count for sets + # Ensure set_bit_count is fully represented + if(set_count % 2 != 0): + set_bit_count += 1 + + self.assoc_bits = Signal(set_bit_count) # Bits for associativity + + # Inputs + self.vma = Signal(36) # Virtual Memory Address (VMA) + + # Output + self.hit = Signal(1) # Denotes if the VMA had a mapped PTE + self.pte = Signal(64) # PTE that was mapped to by the VMA + self.valid = Signal(1) # Denotes if the permissions are correct \ No newline at end of file diff --git a/TLB/src/PermissionValidator.py b/TLB/src/PermissionValidator.py new file mode 100644 index 00000000..7cc12d93 --- /dev/null +++ b/TLB/src/PermissionValidator.py @@ -0,0 +1,61 @@ +from nmigen import Signal +from nmigen.cli import main + +# The purpose of this Module is to check the Permissions of a given PTE +# against the requested access permissions. +# This module will either validate (by setting the valid bit HIGH) the request +# or find a permission fault and invalidate (by setting the valid bit LOW) +# the request +# +# Arguments: +# data_size: (bit count) The size of the data words being processed +# +# Return: +# 1. Data is valid -> valid is HIGH +# 2. Data is not valid -> valid is LOW +class PermissionValidator(): + def __init__(self, data_size): + # Input + self.data = Signal(data_size); + self.xwr = Signal(3) # Execute, Write, Read + self.super = Signal(1) # Supervisor Mode + self.super_access = Signal(1) # Supervisor Access + self.asid = Signal(15) # Address Space IDentifier (ASID) + + # Output + self.valid = Signal(1) # Denotes if the permissions are correct + + def elaborate(self, platform): + m = Module() + m.d.comb += [ + # Check if ASID matches OR entry is global + If(data[64:78] == self.asid or data[5] == 1, + # Check Execute, Write, Read (XWR) Permissions + If(data[3] == self.xwr[2] and data[2] == self.xwr[1] \ + and data[1] == self.xwr[0], + # Check if supervisor + If(self.super == 1, + # Check if entry is in user mode + # Check if supervisor has access + If(data[4] == 0, + self.valid.eq(1) + ).Elif(self.super_access == 1, + self.valid.eq(1) + ).Else( + self.valid.eq(0) + ) + ).Else( + # Check if entry is in user mode + If(data[4] == 1, + self.valid.eq(1) + ).Else( + self.valid.eq(0) + ) + ) + ).Else( + self.valid.eq(0) + ) + ).Else( + self.valid.eq(0) + ) + ] diff --git a/TLB/src/TLB.py b/TLB/src/TLB.py new file mode 100644 index 00000000..b11e49e3 --- /dev/null +++ b/TLB/src/TLB.py @@ -0,0 +1,72 @@ +from nmigen import Memory, Module, Signal +from nmigen.cli import main + +from PermissionValidator import PermissionValidator + +# The expected form of the data is +# Item (Bits) +# Tag (N - 79) / ASID (78 - 64) / PTE (63 - 0) + +class TLB(): + def __init__(self): + # Inputs + self.super = Signal(1) # Supervisor Mode + self.super_access = Signal(1) # Supervisor Access + self.command = Signal(2) # 00=None, 01=Search, 10=Write PTE, 11=Reset + self.xwr = Signal(3) # Execute, Write, Read + self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64 + self.asid = Signal(15) # Address Space IDentifier (ASID) + self.vma = Signal(36) # Virtual Memory Address (VMA) + self.pte_in = Signal(64) # To be saved Page Table Entry (PTE) + + # Outputs + self.hit = Signal(1) # Denotes if the VMA had a mapped PTE + self.valid = Signal(1) # Denotes if the permissions are correct + self.pteOut = Signal(64) # PTE that was mapped to by the VMA + + # Cam simulations + mem_l1 = Memory(113, 32) # L1 TLB cache + read_port_l1 = mem_l1.read_port + write_port_l1 = mem_l1.write_port + + mem_l2 = Memory(113, 128) # L2 TLB cache + read_port_l2 = mem_l2.read_port + write_port_l2 = mem_l2.write_port + + def elaborate(self, platform): + m = Module() + m.d.submodules.perm_valid = perm_valid = PermissionValidator(113) + m.d.sync += [ + Case(self.command, { + # Search for PTE + 1: [ + # Check first entry in set + # TODO make module? + read_port_l1.addr.eq(vma[0,2]), + If(read_port_l1.data[0] == 1, + perm_valid.data.eq(read_port_l1.data), + perm_valid.xwr.eq(self.xwr), + perm_valid.super.eq(self.super), + perm_valid.super_access.eq(self.super_access), + perm_valid.asid.eq(self.asid), + self.valid,eq(perm_valid.valid) + ), + If(self.valid == 0, + read_port_l1.addr.eq(vma[0,2] + 1), + If(read_port_l1.data[0] == 1, + perm_valid.data.eq(read_port_l1.data), + perm_valid.xwr.eq(self.xwr), + perm_valid.super.eq(self.super), + perm_valid.super_access.eq(self.super_access), + perm_valid.asid.eq(self.asid), + self.valid,eq(perm_valid.valid) + ) + ) + ] + }) + ] + return m + +thing = TLB() +print("Gottem") +