build-essential git python3-dev python3-pip
python3-setuptools python3-wheel pkg-config tcl-dev
libreadline-dev bison flex libffi-dev ccache python3-venv
+ binutils-powerpc64-linux-gnu binutils-powerpc64le-linux-gnu
- export PATH="/usr/lib/ccache:$PATH"
- export CCACHE_BASEDIR="$PWD"
- export CCACHE_DIR="$PWD/ccache"
- popd
- python setup.py develop
+ - python src/soc/decoder/pseudo/pywriter.py
- nosetests -v --processes=-1
from nmigen import Module, Signal, Elaboratable
from nmigen.lib.coding import Encoder, PriorityEncoder
+
class AddressEncoder(Elaboratable):
"""Address Encoder
The output is valid when either single or multiple match is high.
Otherwise output is 0.
"""
+
def __init__(self, width):
""" Arguments:
* width: The desired length of the input vector
# Output
self.single_match = Signal(1)
self.multiple_match = Signal(1)
- self.o = Signal(max=width)
+ self.o = Signal(range(width))
def elaborate(self, platform=None):
m = Module()
from nmigen import Array, Cat, Module, Signal, Elaboratable
from nmigen.lib.coding import Decoder
-from nmigen.cli import main #, verilog
+from nmigen.cli import main # , verilog
from .CamEntry import CamEntry
from .AddressEncoder import AddressEncoder
# Input
self.enable = Signal(1)
self.write_enable = Signal(1)
- self.data_in = Signal(data_size) # The data to be written
- self.data_mask = Signal(data_size) # mask for ternary writes
- self.address_in = Signal(max=cam_size) # address of CAM Entry to write
+ self.data_in = Signal(data_size) # The data to be written
+ self.data_mask = Signal(data_size) # mask for ternary writes
+ # address of CAM Entry to write
+ self.address_in = Signal(range(cam_size))
# Output
- self.read_warning = Signal(1) # High when a read interrupts a write
- self.single_match = Signal(1) # High when there is only one match
- self.multiple_match = Signal(1) # High when there at least two matches
- self.match_address = Signal(max=cam_size) # The lowest address matched
+ self.read_warning = Signal(1) # High when a read interrupts a write
+ self.single_match = Signal(1) # High when there is only one match
+ self.multiple_match = Signal(1) # High when there at least two matches
+ # The lowest address matched
+ self.match_address = Signal(range(cam_size))
def elaborate(self, platform=None):
m = Module()
# If the CAM is not enabled set all outputs to 0
with m.Else():
m.d.comb += [
- self.read_warning.eq(0),
- self.single_match.eq(0),
- self.multiple_match.eq(0),
- self.match_address.eq(0)
+ self.read_warning.eq(0),
+ self.single_match.eq(0),
+ self.multiple_match.eq(0),
+ self.match_address.eq(0)
]
return m
def ports(self):
return [self.enable, self.write_enable,
- self.data_in, self.data_mask,
- self.read_warning, self.single_match,
- self.multiple_match, self.match_address]
+ self.data_in, self.data_mask,
+ self.read_warning, self.single_match,
+ self.multiple_match, self.match_address]
if __name__ == '__main__':
cam = Cam(4, 4)
main(cam, ports=cam.ports())
-
class MemorySet(Elaboratable):
def __init__(self, data_size, tag_size, set_count, active):
self.active = active
- input_size = tag_size + data_size # Size of the input data
- memory_width = input_size + 1 # The width of the cache memory
+ input_size = tag_size + data_size # Size of the input data
+ memory_width = input_size + 1 # The width of the cache memory
self.active = active
self.data_size = data_size
self.tag_size = tag_size
# XXX TODO, use rd-enable and wr-enable?
- self.mem = Memory(memory_width, set_count)
+ self.mem = Memory(width=memory_width, depth=set_count)
self.r = self.mem.read_port()
self.w = self.mem.write_port()
# inputs (address)
- self.cset = Signal(max=set_count) # The set to be checked
+ self.cset = Signal(range(set_count)) # The set to be checked
self.tag = Signal(tag_size) # The tag to find
self.data_i = Signal(data_size) # Incoming data
from nmigen import Module, Signal, Elaboratable
from nmigen.cli import main
-from TLB.PteEntry import PteEntry
+from soc.TLB.PteEntry import PteEntry
class PermissionValidator(Elaboratable):
self.pte_entry = PteEntry(asid_size, pte_size)
# Input
- self.data = Signal(asid_size + pte_size);
- self.xwr = Signal(3) # Execute, Write, Read
- self.super_mode = Signal(1) # Supervisor Mode
- self.super_access = Signal(1) # Supervisor Access
- self.asid = Signal(15) # Address Space IDentifier (ASID)
+ self.data = Signal(asid_size + pte_size)
+ self.xwr = Signal(3) # Execute, Write, Read
+ self.super_mode = 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
+ self.valid = Signal(1) # Denotes if the permissions are correct
def elaborate(self, platform=None):
m = Module()
# Valid if entry is not in user mode or supervisor
# has Supervisor User Memory (SUM) access via the
# SUM bit in the sstatus register
- m.d.comb += self.valid.eq((~self.pte_entry.u) \
+ m.d.comb += self.valid.eq((~self.pte_entry.u)
| self.super_access)
# User logic
with m.Else():
from .ariane.plru import PLRU
from .LFSR import LFSR, LFSR_POLY_24
-SA_NA = "00" # no action (none)
-SA_RD = "01" # read
-SA_WR = "10" # write
+SA_NA = "00" # no action (none)
+SA_RD = "01" # read
+SA_WR = "10" # write
class SetAssociativeCache(Elaboratable):
while the ASID provides the tag (still to be decided).
"""
+
def __init__(self, tag_size, data_size, set_count, way_count, lfsr=False):
""" Arguments
* tag_size (bits): The bit count of the tag
self.data_size = data_size # The bit count of the data to be stored
# set up Memory array
- self.mem_array = Array() # memory array
+ self.mem_array = Array() # memory array
for i in range(way_count):
ms = MemorySet(data_size, tag_size, set_count, active=0)
self.mem_array.append(ms)
self.lfsr = LFSR(LFSR_POLY_24)
else:
# PLRU mode
- self.plru = PLRU(way_count) # One block to handle plru calculations
- self.plru_array = Array() # PLRU data on each set
+ # One block to handle plru calculations
+ self.plru = PLRU(way_count)
+ self.plru_array = Array() # PLRU data on each set
for i in range(set_count):
- name="plru%d" % i
+ name = "plru%d" % i
self.plru_array.append(Signal(self.plru.TLBSZ, name=name))
# Input
self.enable = Signal(1) # Whether the cache is enabled
self.command = Signal(2) # 00=None, 01=Read, 10=Write (see SA_XX)
- self.cset = Signal(max=set_count) # The set to be checked
+ self.cset = Signal(range(set_count)) # The set to be checked
self.tag = Signal(tag_size) # The tag to find
self.data_i = Signal(data_size) # The input data
# Output
- self.ready = Signal(1) # 0 => Processing 1 => Ready for commands
+ self.ready = Signal(1) # 0 => Processing 1 => Ready for commands
self.hit = Signal(1) # Tag matched one way in the given set
- self.multiple_hit = Signal(1) # Tag matched many ways in the given set
- self.data_o = Signal(data_size) # The data linked to the matched tag
+ # Tag matched many ways in the given set
+ self.multiple_hit = Signal(1)
+ self.data_o = Signal(data_size) # The data linked to the matched tag
def check_tags(self, m):
""" Validate the tags in the selected set. If one and only one
def write_entry(self, m):
if not self.lfsr_mode:
- m.d.comb += [# set cset (mem address) into PLRU
- self.plru.plru_tree.eq(self.plru_array[self.cset]),
- # and connect plru to encoder for write
- self.encoder.i.eq(self.plru.replace_en_o)
- ]
+ m.d.comb += [ # set cset (mem address) into PLRU
+ self.plru.plru_tree.eq(self.plru_array[self.cset]),
+ # and connect plru to encoder for write
+ self.encoder.i.eq(self.plru.replace_en_o)
+ ]
write_port = self.mem_array[self.encoder.o].w
else:
# use the LFSR to generate a random(ish) one of the mem array
- lfsr_output = Signal(max=self.way_count)
- lfsr_random = Signal(max=self.way_count)
- m.d.comb += lfsr_output.eq(self.lfsr.state) # lose some bits
+ lfsr_output = Signal(range(self.way_count))
+ lfsr_random = Signal(range(self.way_count))
+ m.d.comb += lfsr_output.eq(self.lfsr.state) # lose some bits
# address too big, limit to range of array
m.d.comb += lfsr_random.eq(Mux(lfsr_output > self.way_count,
lfsr_output - self.way_count,
with m.State("READY"):
m.d.comb += self.ready.eq(0)
self.write_entry(m)
- m.next ="FINISHED_WRITE"
+ m.next = "FINISHED_WRITE"
with m.State("FINISHED_WRITE"):
m.d.comb += self.ready.eq(1)
if not self.lfsr_mode:
m.d.sync += plru_entry.eq(self.plru.plru_tree_o)
m.next = "READY"
-
def elaborate(self, platform=None):
m = Module()
m.d.comb += [mem.cset.eq(self.cset),
mem.tag.eq(self.tag),
mem.data_i.eq(self.data_i),
- write_port.en.eq(0), # default: disable write
- ]
+ write_port.en.eq(0), # default: disable write
+ ]
# ----
# Commands: READ/WRITE/TODO
# ----
from .PermissionValidator import PermissionValidator
from .Cam import Cam
+
class TLB(Elaboratable):
def __init__(self, asid_size, vma_size, pte_size, L1_size):
""" Arguments
self.state = 0
# L1 Cache Modules
self.cam_L1 = Cam(vma_size, L1_size)
- self.mem_L1 = Memory(asid_size + pte_size, L1_size)
+ self.mem_L1 = Memory(width=asid_size + pte_size, depth=L1_size)
# Permission Validator
self.perm_validator = PermissionValidator(asid_size, pte_size)
# Inputs
- self.supermode = Signal(1) # Supervisor Mode
- self.super_access = Signal(1) # Supervisor Access
- self.command = Signal(2) # 00=None, 01=Search, 10=Write L1, 11=Write L2
- self.xwr = Signal(3) # Execute, Write, Read
- self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64
- self.address_L1 = Signal(max=L1_size)
- self.asid = Signal(asid_size) # Address Space IDentifier (ASID)
- self.vma = Signal(vma_size) # Virtual Memory Address (VMA)
- self.pte_in = Signal(pte_size) # To be saved Page Table Entry (PTE)
+ self.supermode = Signal(1) # Supervisor Mode
+ self.super_access = Signal(1) # Supervisor Access
+ # 00=None, 01=Search, 10=Write L1, 11=Write L2
+ self.command = Signal(2)
+ self.xwr = Signal(3) # Execute, Write, Read
+ self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64
+ self.address_L1 = Signal(range(L1_size))
+ self.asid = Signal(asid_size) # Address Space IDentifier (ASID)
+ self.vma = Signal(vma_size) # Virtual Memory Address (VMA)
+ self.pte_in = Signal(pte_size) # To be saved Page Table Entry (PTE)
# Outputs
- self.hit = Signal(1) # Denotes if the VMA had a mapped PTE
- self.perm_valid = Signal(1) # Denotes if the permissions are correct
- self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA
+ self.hit = Signal(1) # Denotes if the VMA had a mapped PTE
+ self.perm_valid = Signal(1) # Denotes if the permissions are correct
+ self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA
def search(self, m, read_L1, write_L1):
""" searches the TLB
# Match found in L1 CAM
match_found = Signal(reset_less=True)
m.d.comb += match_found.eq(self.cam_L1.single_match
- | self.cam_L1.multiple_match)
+ | self.cam_L1.multiple_match)
with m.If(match_found):
# Memory shortcut variables
mem_address = self.cam_L1.match_address
# CAM_L1 Logic
m.d.comb += [
self.cam_L1.write_enable.eq(1),
- self.cam_L1.data_in.eq(self.vma), #data_in is sent to all entries
+ self.cam_L1.data_in.eq(self.vma), # data_in is sent to all entries
# self.cam_L1.address_in.eq(todo) # a CAM entry needs to be selected
-
+
]
def elaborate(self, platform):
m.submodules.cam_L1 = self.cam_L1
m.submodules.read_L1 = read_L1 = self.mem_L1.read_port()
m.submodules.write_L1 = write_L1 = self.mem_L1.write_port()
-
+
# Permission Validator Submodule
m.submodules.perm_valididator = self.perm_validator
self.write_l1(m, read_L1, write_L1)
# TODO
- #with m.Case("11"):
+ # with m.Case("11"):
# When disabled
with m.Else():
self.cam_L1.enable.eq(0),
# XXX TODO - self.reg_file.enable.eq(0),
self.hit.eq(0),
- self.perm_valid.eq(0), # XXX TODO, check this
+ self.perm_valid.eq(0), # XXX TODO, check this
self.pte_out.eq(0)
]
return m
if __name__ == '__main__':
tlb = TLB(15, 36, 64, 4)
- main(tlb, ports=[ tlb.supermode, tlb.super_access, tlb.command,
- tlb.xwr, tlb.mode, tlb.address_L1, tlb.asid,
- tlb.vma, tlb.pte_in,
- tlb.hit, tlb.perm_valid, tlb.pte_out,
- ] + tlb.cam_L1.ports())
+ main(tlb, ports=[tlb.supermode, tlb.super_access, tlb.command,
+ tlb.xwr, tlb.mode, tlb.address_L1, tlb.asid,
+ tlb.vma, tlb.pte_in,
+ tlb.hit, tlb.perm_valid, tlb.pte_out,
+ ] + tlb.cam_L1.ports())
import sys
-sys.path.append("../src")
-sys.path.append("../../../TestUtil")
-
-from TLB.ariane.plru import PLRU
-
+from soc.TLB.ariane.plru import PLRU
from nmigen.compat.sim import run_simulation
+
def tbench(dut):
yield
+
if __name__ == "__main__":
dut = PLRU(4)
run_simulation(dut, tbench(dut), vcd_name="test_plru.vcd")
-import sys
-sys.path.append("../src")
-sys.path.append("../../../TestUtil")
-
from nmigen.compat.sim import run_simulation
-
-from TLB.ariane.ptw import PTW, PTE
+from soc.TLB.ariane.ptw import PTW, PTE
# unit was changed, test needs to be changed
+
def tbench(dut):
addr = 0x8000000
#pte = PTE()
- #yield pte.v.eq(1)
- #yield pte.r.eq(1)
+ # yield pte.v.eq(1)
+ # yield pte.r.eq(1)
yield dut.req_port_i.data_gnt.eq(1)
yield dut.req_port_i.data_rvalid.eq(1)
- yield dut.req_port_i.data_rdata.eq(0x43)#pte.flatten())
+ yield dut.req_port_i.data_rdata.eq(0x43) # pte.flatten())
# data lookup
yield dut.en_ld_st_translation_i.eq(1)
yield dut.mxr_i.eq(0x1)
yield dut.req_port_i.data_gnt.eq(1)
yield dut.req_port_i.data_rvalid.eq(1)
- yield dut.req_port_i.data_rdata.eq(0x41 | (addr>>12)<<10)#pte.flatten())
+ # pte.flatten())
+ yield dut.req_port_i.data_rdata.eq(0x41 | (addr >> 12) << 10)
yield dut.en_ld_st_translation_i.eq(1)
yield dut.asid_i.eq(1)
yield
yield
-
# instruction lookup
yield dut.en_ld_st_translation_i.eq(0)
yield dut.enable_translation_i.eq(1)
run_simulation(dut, tbench(dut), vcd_name="test_ptw.vcd")
print("PTW Unit Test Success")
+
if __name__ == "__main__":
test_ptw()
-import sys
-sys.path.append("../src")
-sys.path.append("../../../TestUtil")
-
from nmigen.compat.sim import run_simulation
-from TLB.ariane.tlb import TLB
+from soc.TLB.ariane.tlb import TLB
+
def set_vaddr(addr):
yield dut.lu_vaddr_i.eq(addr)
- yield dut.update_i.vpn.eq(addr>>12)
+ yield dut.update_i.vpn.eq(addr >> 12)
def tbench(dut):
-import sys
-sys.path.append("../src")
-sys.path.append("../../../TestUtil")
-
from nmigen.compat.sim import run_simulation
-from TLB.ariane.tlb_content import TLBContent
-from TestUtil.test_helper import assert_op, assert_eq
+from soc.TLB.ariane.tlb_content import TLBContent
+from soc.TestUtil.test_helper import assert_op, assert_eq
+
-def update(dut,a,t,g,m):
+def update(dut, a, t, g, m):
yield dut.replace_en_i.eq(1)
yield dut.update_i.valid.eq(1)
yield dut.update_i.is_512G.eq(t)
yield
yield
-def check_hit(dut,hit,pagesize):
+
+def check_hit(dut, hit, pagesize):
hit_d = yield dut.lu_hit_o
assert_eq("hit", hit_d, hit)
if(hit):
- if(pagesize=="t"):
+ if(pagesize == "t"):
hitp = yield dut.lu_is_512G_o
assert_eq("lu_is_512G_o", hitp, 1)
- elif(pagesize=="g"):
+ elif(pagesize == "g"):
hitp = yield dut.lu_is_1G_o
assert_eq("lu_is_1G_o", hitp, 1)
- elif(pagesize=="m"):
+ elif(pagesize == "m"):
hitp = yield dut.lu_is_2M_o
assert_eq("lu_is_2M_o", hitp, 1)
-def addr(a,b,c,d):
- return a | b << 9 | c << 18 | d << 27
-
+
+def addr(a, b, c, d):
+ return a | b << 9 | c << 18 | d << 27
+
+
def tbench(dut):
yield dut.vpn0.eq(0x0A)
yield dut.vpn1.eq(0x0B)
yield dut.vpn2.eq(0x0C)
yield dut.vpn3.eq(0x0D)
- yield from update(dut,addr(0xFF,0xFF,0xFF,0x0D),1,0,0)
- yield from check_hit(dut,1,"t")
-
- yield from update(dut,addr(0xFF,0xFF,0x0C,0x0D),0,1,0)
- yield from check_hit(dut,1,"g")
-
- yield from update(dut,addr(0xFF,0x0B,0x0C,0x0D),0,0,1)
- yield from check_hit(dut,1,"m")
-
- yield from update(dut,addr(0x0A,0x0B,0x0C,0x0D),0,0,0)
- yield from check_hit(dut,1,"")
-
- yield from update(dut,addr(0xAA,0xBB,0xCC,0xDD),0,0,0)
- yield from check_hit(dut,0,"miss")
-
+ yield from update(dut, addr(0xFF, 0xFF, 0xFF, 0x0D), 1, 0, 0)
+ yield from check_hit(dut, 1, "t")
+
+ yield from update(dut, addr(0xFF, 0xFF, 0x0C, 0x0D), 0, 1, 0)
+ yield from check_hit(dut, 1, "g")
+
+ yield from update(dut, addr(0xFF, 0x0B, 0x0C, 0x0D), 0, 0, 1)
+ yield from check_hit(dut, 1, "m")
+
+ yield from update(dut, addr(0x0A, 0x0B, 0x0C, 0x0D), 0, 0, 0)
+ yield from check_hit(dut, 1, "")
+
+ yield from update(dut, addr(0xAA, 0xBB, 0xCC, 0xDD), 0, 0, 0)
+ yield from check_hit(dut, 0, "miss")
+
if __name__ == "__main__":
- dut = TLBContent(4,4)
+ dut = TLBContent(4, 4)
#
run_simulation(dut, tbench(dut), vcd_name="test_tlb_content.vcd")
print("TLBContent Unit Test Success")
from nmigen.cli import verilog, rtlil
from nmigen.lib.coding import Encoder
-from TLB.ariane.ptw import TLBUpdate, PTE, ASID_WIDTH
-from TLB.ariane.plru import PLRU
-from TLB.ariane.tlb_content import TLBContent
+from soc.TLB.ariane.ptw import TLBUpdate, PTE, ASID_WIDTH
+from soc.TLB.ariane.plru import PLRU
+from soc.TLB.ariane.tlb_content import TLBContent
TLB_ENTRIES = 8
+
class TLB(Elaboratable):
def __init__(self, tlb_entries=8, asid_width=8):
self.tlb_entries = tlb_entries
def elaborate(self, platform):
m = Module()
- vpn3 = Signal(9) #FIXME unused signal
+ vpn3 = Signal(9) # FIXME unused signal
vpn2 = Signal(9)
vpn1 = Signal(9)
vpn0 = Signal(9)
- #-------------
+ # -------------
# Translation
- #-------------
+ # -------------
# SV48 defines four levels of page tables
- m.d.comb += [ vpn0.eq(self.lu_vaddr_i[12:21]),
- vpn1.eq(self.lu_vaddr_i[21:30]),
- vpn2.eq(self.lu_vaddr_i[30:39]),
- vpn3.eq(self.lu_vaddr_i[39:48]), ### FIXME
- ]
+ m.d.comb += [vpn0.eq(self.lu_vaddr_i[12:21]),
+ vpn1.eq(self.lu_vaddr_i[21:30]),
+ vpn2.eq(self.lu_vaddr_i[30:39]),
+ vpn3.eq(self.lu_vaddr_i[39:48]), # FIXME
+ ]
tc = []
for i in range(self.tlb_entries):
tlc.vpn2.eq(vpn2),
# TODO 4th
tlc.flush_i.eq(self.flush_i),
- #tlc.update_i.eq(self.update_i),
+ # tlc.update_i.eq(self.update_i),
tlc.lu_asid_i.eq(self.lu_asid_i)]
tc = Array(tc)
- #--------------
+ # --------------
# Select hit
- #--------------
+ # --------------
# use Encoder to select hit index
# XXX TODO: assert that there's only one valid entry (one lu_hit)
hits = []
for i in range(self.tlb_entries):
hits.append(tc[i].lu_hit_o)
- m.d.comb += hitsel.i.eq(Cat(*hits)) # (goes into plru as well)
+ m.d.comb += hitsel.i.eq(Cat(*hits)) # (goes into plru as well)
idx = hitsel.o
active = Signal(reset_less=True)
m.d.comb += active.eq(~hitsel.n)
with m.If(active):
# active hit, send selected as output
- m.d.comb += [ self.lu_is_512G_o.eq(tc[idx].lu_is_512G_o),
- self.lu_is_1G_o.eq(tc[idx].lu_is_1G_o),
- self.lu_is_2M_o.eq(tc[idx].lu_is_2M_o),
- self.lu_hit_o.eq(1),
- self.lu_content_o.flatten().eq(tc[idx].lu_content_o),
- ]
-
- #--------------
+ m.d.comb += [self.lu_is_512G_o.eq(tc[idx].lu_is_512G_o),
+ self.lu_is_1G_o.eq(tc[idx].lu_is_1G_o),
+ self.lu_is_2M_o.eq(tc[idx].lu_is_2M_o),
+ self.lu_hit_o.eq(1),
+ self.lu_content_o.flatten().eq(tc[idx].lu_content_o),
+ ]
+
+ # --------------
# PLRU.
- #--------------
+ # --------------
p = PLRU(self.tlb_entries)
plru_tree = Signal(p.TLBSZ)
en = []
for i in range(self.tlb_entries):
en.append(tc[i].replace_en_i)
- m.d.comb += [Cat(*en).eq(p.replace_en_o), # output from PLRU into tags
+ m.d.comb += [Cat(*en).eq(p.replace_en_o), # output from PLRU into tags
p.lu_hit.eq(hitsel.i),
p.lu_access_i.eq(self.lu_access_i),
p.plru_tree.eq(plru_tree)]
m.d.sync += plru_tree.eq(p.plru_tree_o)
- #--------------
+ # --------------
# Sanity checks
- #--------------
+ # --------------
assert (self.tlb_entries % 2 == 0) and (self.tlb_entries > 1), \
"TLB size must be a multiple of 2 and greater than 1"
def ports(self):
return [self.flush_i, self.lu_access_i,
- self.lu_asid_i, self.lu_vaddr_i,
- self.lu_is_2M_o, self.lu_1G_o, self.lu_is_512G_o, self.lu_hit_o
+ self.lu_asid_i, self.lu_vaddr_i,
+ self.lu_is_2M_o, self.lu_1G_o, self.lu_is_512G_o, self.lu_hit_o
] + self.lu_content_o.ports() + self.update_i.ports()
+
if __name__ == '__main__':
tlb = TLB()
vl = rtlil.convert(tlb, ports=tlb.ports())
with open("test_tlb.il", "w") as f:
f.write(vl)
-
from nmigen import Signal, Module, Cat, Const, Elaboratable
-from TLB.ariane.ptw import TLBUpdate, PTE
+from soc.TLB.ariane.ptw import TLBUpdate, PTE
class TLBEntry:
def __init__(self, asid_width):
- self.asid = Signal(asid_width,name="ent_asid")
+ self.asid = Signal(asid_width, name="ent_asid")
# SV48 defines four levels of page tables
- self.vpn0 = Signal(9,name="ent_vpn0")
- self.vpn1 = Signal(9,name="ent_vpn1")
- self.vpn2 = Signal(9,name="ent_vpn2")
- self.vpn3 = Signal(9,name="ent_vpn3")
+ self.vpn0 = Signal(9, name="ent_vpn0")
+ self.vpn1 = Signal(9, name="ent_vpn1")
+ self.vpn2 = Signal(9, name="ent_vpn2")
+ self.vpn3 = Signal(9, name="ent_vpn3")
self.is_2M = Signal(name="ent_is_2M")
self.is_1G = Signal(name="ent_is_1G")
self.is_512G = Signal(name="ent_is_512G")
self.valid = Signal(name="ent_valid")
-
+
def flatten(self):
return Cat(*self.ports())
def ports(self):
return [self.asid, self.vpn0, self.vpn1, self.vpn2,
self.is_2M, self.is_1G, self.valid]
-
+
class TLBContent(Elaboratable):
def __init__(self, pte_width, asid_width):
self.vpn2 = Signal(9)
self.vpn1 = Signal(9)
self.vpn0 = Signal(9)
- self.replace_en_i = Signal() # replace the following entry,
- # set by replacement strategy
+ self.replace_en_i = Signal() # replace the following entry,
+ # set by replacement strategy
# Lookup signals
self.lu_asid_i = Signal(asid_width)
self.lu_content_o = Signal(pte_width)
m = Module()
tags = TLBEntry(self.asid_width)
-
-
+
content = Signal(self.pte_width)
m.d.comb += [self.lu_hit_o.eq(0),
#tags_2M = Signal(reset_less=True)
vpn0_or_2M = Signal(reset_less=True)
-
+
m.d.comb += [
- #compare asid and vpn*
- asid_ok.eq(tags.asid == self.lu_asid_i),
- vpn3_ok.eq(tags.vpn3 == self.vpn3),
- vpn2_ok.eq(tags.vpn2 == self.vpn2),
- vpn1_ok.eq(tags.vpn1 == self.vpn1),
- vpn0_ok.eq(tags.vpn0 == self.vpn0),
- vpn0_or_2M.eq(tags.is_2M | vpn0_ok)
+ # compare asid and vpn*
+ asid_ok.eq(tags.asid == self.lu_asid_i),
+ vpn3_ok.eq(tags.vpn3 == self.vpn3),
+ vpn2_ok.eq(tags.vpn2 == self.vpn2),
+ vpn1_ok.eq(tags.vpn1 == self.vpn1),
+ vpn0_ok.eq(tags.vpn0 == self.vpn0),
+ vpn0_or_2M.eq(tags.is_2M | vpn0_ok)
]
-
-
+
with m.If(asid_ok & tags.valid):
# first level, only vpn3 needs to match
- with m.If (tags.is_512G & vpn3_ok):
- m.d.comb += [ self.lu_content_o.eq(content),
- self.lu_is_512G_o.eq(1),
- self.lu_hit_o.eq(1),
- ]
+ with m.If(tags.is_512G & vpn3_ok):
+ m.d.comb += [self.lu_content_o.eq(content),
+ self.lu_is_512G_o.eq(1),
+ self.lu_hit_o.eq(1),
+ ]
# second level , second level vpn2 and vpn3 need to match
- with m.Elif (tags.is_1G & vpn2_ok & vpn3_ok):
- m.d.comb += [ self.lu_content_o.eq(content),
- self.lu_is_1G_o.eq(1),
- self.lu_hit_o.eq(1),
- ]
+ with m.Elif(tags.is_1G & vpn2_ok & vpn3_ok):
+ m.d.comb += [self.lu_content_o.eq(content),
+ self.lu_is_1G_o.eq(1),
+ self.lu_hit_o.eq(1),
+ ]
# not a giga page hit nor a tera page hit so check further
with m.Elif(vpn1_ok):
# this could be a 2 mega page hit or a 4 kB hit
# output accordingly
with m.If(vpn0_or_2M):
- m.d.comb += [ self.lu_content_o.eq(content),
- self.lu_is_2M_o.eq(tags.is_2M),
- self.lu_hit_o.eq(1),
- ]
+ m.d.comb += [self.lu_content_o.eq(content),
+ self.lu_is_2M_o.eq(tags.is_2M),
+ self.lu_hit_o.eq(1),
+ ]
# ------------------
# Update or Flush
# ------------------
m.d.comb += replace_valid.eq(self.update_i.valid & self.replace_en_i)
# flush
- with m.If (self.flush_i):
+ with m.If(self.flush_i):
# invalidate (flush) conditions: all if zero or just this ASID
- with m.If (self.lu_asid_i == Const(0, self.asid_width) |
+ with m.If(self.lu_asid_i == Const(0, self.asid_width) |
(self.lu_asid_i == tags.asid)):
m.d.sync += tags.valid.eq(0)
# normal replacement
with m.Elif(replace_valid):
- m.d.sync += [ # update tag array
- tags.asid.eq(self.update_i.asid),
- tags.vpn3.eq(self.update_i.vpn[27:36]),
- tags.vpn2.eq(self.update_i.vpn[18:27]),
- tags.vpn1.eq(self.update_i.vpn[9:18]),
- tags.vpn0.eq(self.update_i.vpn[0:9]),
- tags.is_512G.eq(self.update_i.is_512G),
- tags.is_1G.eq(self.update_i.is_1G),
- tags.is_2M.eq(self.update_i.is_2M),
- tags.valid.eq(1),
- # and content as well
- content.eq(self.update_i.content.flatten())
- ]
+ m.d.sync += [ # update tag array
+ tags.asid.eq(self.update_i.asid),
+ tags.vpn3.eq(self.update_i.vpn[27:36]),
+ tags.vpn2.eq(self.update_i.vpn[18:27]),
+ tags.vpn1.eq(self.update_i.vpn[9:18]),
+ tags.vpn0.eq(self.update_i.vpn[0:9]),
+ tags.is_512G.eq(self.update_i.is_512G),
+ tags.is_1G.eq(self.update_i.is_1G),
+ tags.is_2M.eq(self.update_i.is_2M),
+ tags.valid.eq(1),
+ # and content as well
+ content.eq(self.update_i.content.flatten())
+ ]
return m
def ports(self):
return [self.flush_i,
- self.lu_asid_i,
- self.lu_is_2M_o, self.lu_is_1G_o,self.lu_is_512G_o, self.lu_hit_o,
+ self.lu_asid_i,
+ self.lu_is_2M_o, self.lu_is_1G_o, self.lu_is_512G_o, self.lu_hit_o,
] + self.update_i.content.ports() + self.update_i.ports()
# SPDX-License-Identifier: LGPL-2.1-or-later
# See Notices.txt for copyright information
-from TLB.LFSR import LFSR, LFSRPolynomial, LFSR_POLY_3
+from soc.TLB.LFSR import LFSR, LFSRPolynomial, LFSR_POLY_3
from nmigen.back.pysim import Simulator, Delay, Tick
import unittest
vcd_file=open("Waveforms/test_LFSR2.vcd", "w"),
gtkw_file=open("Waveforms/test_LFSR2.gtkw", "w"),
traces=traces) as sim:
- sim.add_clock(1e-6, 0.25e-6)
+ sim.add_clock(1e-6, phase=0.25e-6)
delay = Delay(1e-7)
def async_process():
sim.add_process(async_process)
sim.run()
-
from nmigen.compat.sim import run_simulation
-from TLB.AddressEncoder import AddressEncoder
-from TestUtil.test_helper import assert_eq, assert_ne, assert_op
+from soc.TLB.AddressEncoder import AddressEncoder
+from soc.TestUtil.test_helper import assert_eq, assert_ne, assert_op
# This function allows for the easy setting of values to the AddressEncoder
# dut: The AddressEncoder being tested
# sm (Single Match): The expected match result
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_single_match(dut, sm, op):
out_sm = yield dut.single_match
assert_op("Single Match", out_sm, sm, op)
# dut: The AddressEncoder being tested
# mm (Multiple Match): The expected match result
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_multiple_match(dut, mm, op):
out_mm = yield dut.multiple_match
assert_op("Multiple Match", out_mm, mm, op)
# dut: The AddressEncoder being tested
# o (Output): The expected output
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_output(dut, o, op):
out_o = yield dut.o
assert_op("Output", out_o, o, op)
# ss_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
# mm_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
# o_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
+
+
def check_all(dut, sm, mm, o, sm_op, mm_op, o_op):
yield from check_single_match(dut, sm, sm_op)
yield from check_multiple_match(dut, mm, mm_op)
yield from check_output(dut, o, o_op)
+
def tbench(dut):
# Check invalid input
in_val = 0b000
yield from set_encoder(dut, in_val)
yield from check_all(dut, single_match, multiple_match, output, 0, 0, 0)
+
def test_addr():
dut = AddressEncoder(4)
- run_simulation(dut, tbench(dut),
+ run_simulation(dut, tbench(dut),
vcd_name="Waveforms/test_address_encoder.vcd")
print("AddressEncoder Unit Test Success")
+
if __name__ == "__main__":
test_addr()
from nmigen.compat.sim import run_simulation
-from TLB.Cam import Cam
+from soc.TLB.Cam import Cam
-from TestUtil.test_helper import assert_eq, assert_ne, assert_op
+from soc.TestUtil.test_helper import assert_eq, assert_ne, assert_op
# This function allows for the easy setting of values to the Cam
# Arguments:
# we (Write Enable): Whether the Cam will write on the next cycle
# a (Address): Where the data will be written if write enable is high
# d (Data): Either what we are looking for or will write to the address
+
+
def set_cam(dut, e, we, a, d):
yield dut.enable.eq(e)
yield dut.write_enable.eq(we)
# dut: The Cam being tested
# mm (Multiple Match): The expected match result
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_multiple_match(dut, mm, op):
out_mm = yield dut.multiple_match
assert_op("Multiple Match", out_mm, mm, op)
# dut: The Cam being tested
# sm (Single Match): The expected match result
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_single_match(dut, sm, op):
out_sm = yield dut.single_match
assert_op("Single Match", out_sm, sm, op)
# dut: The Cam being tested
# ma (Match Address): The expected match result
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_match_address(dut, ma, op):
out_ma = yield dut.match_address
assert_op("Match Address", out_ma, ma, op)
# ss_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
# mm_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
# ma_op (Operation): Operation for the address assertion (0 => ==), (1 => !=)
+
+
def check_all(dut, mm, sm, ma, mm_op, sm_op, ma_op):
yield from check_multiple_match(dut, mm, mm_op)
yield from check_single_match(dut, sm, sm_op)
yield from check_match_address(dut, ma, ma_op)
+
def tbench(dut):
# NA
enable = 0
single_match = 0
yield from set_cam(dut, enable, write_enable, address, data)
yield
- yield from check_all(dut, multiple_match, single_match, address,0,0,0)
+ yield from check_all(dut, multiple_match, single_match, address, 0, 0, 0)
# Verify read_warning is not caused
# Write Entry 0
run_simulation(dut, tbench(dut), vcd_name="Waveforms/test_cam.vcd")
print("Cam Unit Test Success")
+
if __name__ == "__main__":
test_cam()
from nmigen.compat.sim import run_simulation
-from TestUtil.test_helper import assert_eq, assert_ne, assert_op
-from TLB.CamEntry import CamEntry
+from soc.TestUtil.test_helper import assert_eq, assert_ne, assert_op
+from soc.TLB.CamEntry import CamEntry
# This function allows for the easy setting of values to the Cam Entry
# Arguments:
# dut: The CamEntry being tested
# c (command): NA (0), Read (1), Write (2), Reserve (3)
# d (data): The data to be set
+
+
def set_cam_entry(dut, c, d):
# Write desired values
yield dut.command.eq(c)
# dut: The CamEntry being tested
# d (Data): The expected data
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_data(dut, d, op):
out_d = yield dut.data
assert_op("Data", out_d, d, op)
# dut: The CamEntry being tested
# m (Match): The expected match
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_match(dut, m, op):
out_m = yield dut.match
assert_op("Match", out_m, m, op)
# m (match): The expected match
# d_op (Operation): Operation for the data assertion (0 => ==), (1 => !=)
# m_op (Operation): Operation for the match assertion (0 => ==), (1 => !=)
+
+
def check_all(dut, d, m, d_op, m_op):
yield from check_data(dut, d, d_op)
yield from check_match(dut, m, m_op)
# It is done by writing and then reading various combinations of key/data pairs
# and reading the results with varying keys to verify the resulting stored
# data is correct.
+
+
def tbench(dut):
# Check write
command = 2
if __name__ == "__main__":
test_camentry()
-
from nmigen.compat.sim import run_simulation
-from TLB.PermissionValidator import PermissionValidator
+from soc.TLB.PermissionValidator import PermissionValidator
-from TestUtil.test_helper import assert_op
+from soc.TestUtil.test_helper import assert_op
def set_validator(dut, d, xwr, sm, sa, asid):
yield dut.asid.eq(asid)
yield
+
def check_valid(dut, v, op):
out_v = yield dut.valid
assert_op("Valid", out_v, v, op)
+
def tbench(dut):
# 80 bits represented. Ignore the MSB as it will be truncated
# ASID is bits first 4 hex values (bits 64 - 78)
def test_permv():
- dut = PermissionValidator(15, 64);
- run_simulation(dut, tbench(dut), vcd_name="Waveforms/test_permission_validator.vcd")
+ dut = PermissionValidator(15, 64)
+ run_simulation(dut, tbench(
+ dut), vcd_name="Waveforms/test_permission_validator.vcd")
print("PermissionValidator Unit Test Success")
+
if __name__ == "__main__":
test_permv()
from nmigen.compat.sim import run_simulation
-from TLB.PteEntry import PteEntry
+from soc.TLB.PteEntry import PteEntry
+
+from soc.TestUtil.test_helper import assert_op
-from TestUtil.test_helper import assert_op
def set_entry(dut, i):
yield dut.i.eq(i)
yield
+
def check_dirty(dut, d, op):
out_d = yield dut.d
assert_op("Dirty", out_d, d, op)
+
def check_accessed(dut, a, op):
out_a = yield dut.a
assert_op("Accessed", out_a, a, op)
+
def check_global(dut, o, op):
out = yield dut.g
assert_op("Global", out, o, op)
+
def check_user(dut, o, op):
out = yield dut.u
assert_op("User Mode", out, o, op)
+
def check_xwr(dut, o, op):
out = yield dut.xwr
assert_op("XWR", out, o, op)
+
def check_asid(dut, o, op):
out = yield dut.asid
assert_op("ASID", out, o, op)
+
def check_pte(dut, o, op):
out = yield dut.pte
assert_op("ASID", out, o, op)
+
def check_valid(dut, v, op):
out_v = yield dut.v
assert_op("Valid", out_v, v, op)
+
def check_all(dut, d, a, g, u, xwr, v, asid, pte):
yield from check_dirty(dut, d, 0)
yield from check_accessed(dut, a, 0)
yield from check_pte(dut, pte, 0)
yield from check_valid(dut, v, 0)
+
def tbench(dut):
# 80 bits represented. Ignore the MSB as it will be truncated
# ASID is bits first 4 hex values (bits 64 - 78)
def test_pteentry():
- dut = PteEntry(15, 64);
+ dut = PteEntry(15, 64)
run_simulation(dut, tbench(dut), vcd_name="Waveforms/test_pte_entry.vcd")
print("PteEntry Unit Test Success")
+
if __name__ == "__main__":
test_pteentry()
from nmigen.compat.sim import run_simulation
-from TLB.SetAssociativeCache import SetAssociativeCache
+from soc.TLB.SetAssociativeCache import SetAssociativeCache
+
+from soc.TestUtil.test_helper import assert_eq, assert_ne, assert_op
-from TestUtil.test_helper import assert_eq, assert_ne, assert_op
def set_sac(dut, e, c, s, t, d):
yield dut.enable.eq(e)
yield dut.data_i.eq(d)
yield
+
def tbench(dut):
enable = 1
command = 2
yield from set_sac(dut, enable, command, cset, tag, data)
yield
+
def test_assoc_cache():
dut = SetAssociativeCache(4, 4, 4, 4)
- run_simulation(dut, tbench(dut), vcd_name="Waveforms/test_set_associative_cache.vcd")
+ run_simulation(dut, tbench(
+ dut), vcd_name="Waveforms/test_set_associative_cache.vcd")
print("Set Associative Cache Unit Test Success")
+
if __name__ == "__main__":
test_assoc_cache()
#import tracemalloc
-#tracemalloc.start()
+# tracemalloc.start()
from nmigen.compat.sim import run_simulation
-from TLB.TLB import TLB
+from soc.TLB.TLB import TLB
-from TestUtil.test_helper import assert_op, assert_eq
+from soc.TestUtil.test_helper import assert_op, assert_eq
-#self.supermode = Signal(1) # Supervisor Mode
-#self.super_access = Signal(1) # Supervisor Access
-#self.command = Signal(2) # 00=None, 01=Search, 10=Write L1, 11=Write L2
-#self.xwr = Signal(3) # Execute, Write, Read
-#self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64
-#self.address_L1 = Signal(max=L1_size)
-#self.asid = Signal(asid_size) # Address Space IDentifier (ASID)
-#self.vma = Signal(vma_size) # Virtual Memory Address (VMA)
-#self.pte_in = Signal(pte_size) # To be saved Page Table Entry (PTE)
+# self.supermode = Signal(1) # Supervisor Mode
+# self.super_access = Signal(1) # Supervisor Access
+# self.command = Signal(2) # 00=None, 01=Search, 10=Write L1, 11=Write L2
+# self.xwr = Signal(3) # Execute, Write, Read
+# self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64
+#self.address_L1 = Signal(range(L1_size))
+# self.asid = Signal(asid_size) # Address Space IDentifier (ASID)
+# self.vma = Signal(vma_size) # Virtual Memory Address (VMA)
+# self.pte_in = Signal(pte_size) # To be saved Page Table Entry (PTE)
#
-#self.hit = Signal(1) # Denotes if the VMA had a mapped PTE
-#self.perm_valid = Signal(1) # Denotes if the permissions are correct
-#self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA
+# self.hit = Signal(1) # Denotes if the VMA had a mapped PTE
+# self.perm_valid = Signal(1) # Denotes if the permissions are correct
+# self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA
-COMMAND_READ=1
-COMMAND_WRITE_L1=2
+COMMAND_READ = 1
+COMMAND_WRITE_L1 = 2
# Checks the data state of the CAM entry
# Arguments:
# dut: The CamEntry being tested
# d (Data): The expected data
# op (Operation): (0 => ==), (1 => !=)
+
+
def check_hit(dut, d):
hit_d = yield dut.hit
#assert_eq("hit", hit_d, d)
-def test_command(dut,cmd,xwr,cycles):
+
+def tst_command(dut, cmd, xwr, cycles):
yield dut.command.eq(cmd)
yield dut.xwr.eq(xwr)
- for i in range(0,cycles):
+ for i in range(0, cycles):
yield
-def test_write_L1(dut,vma,address_L1,asid,pte_in):
+
+def tst_write_L1(dut, vma, address_L1, asid, pte_in):
yield dut.address_L1.eq(address_L1)
yield dut.asid.eq(asid)
yield dut.vma.eq(vma)
yield dut.pte_in.eq(pte_in)
- yield from test_command(dut,COMMAND_WRITE_L1,7,2)
+ yield from tst_command(dut, COMMAND_WRITE_L1, 7, 2)
-def test_search(dut,vma,found):
+
+def tst_search(dut, vma, found):
yield dut.vma.eq(vma)
- yield from test_command(dut,COMMAND_READ,7,1)
- yield from check_hit(dut,found)
+ yield from tst_command(dut, COMMAND_READ, 7, 1)
+ yield from check_hit(dut, found)
+
def zero(dut):
yield dut.supermode.eq(0)
yield dut.vma.eq(0)
yield dut.pte_in.eq(0)
+
def tbench(dut):
yield from zero(dut)
- yield dut.mode.eq(0xF) # enable TLB
- #test hit
- yield from test_write_L1(dut,0xFEEDFACE,0,0xFFFF,0xF0F0)
- yield from test_search(dut,0xFEEDFACE,1)
- yield from test_search(dut,0xFACEFEED,0)
-
+ yield dut.mode.eq(0xF) # enable TLB
+ # test hit
+ yield from tst_write_L1(dut, 0xFEEDFACE, 0, 0xFFFF, 0xF0F0)
+ yield from tst_search(dut, 0xFEEDFACE, 1)
+ yield from tst_search(dut, 0xFACEFEED, 0)
-
def test_tlb():
- dut = TLB(15,36,64,8)
+ dut = TLB(15, 36, 64, 8)
run_simulation(dut, tbench(dut), vcd_name="Waveforms/test_tlb.vcd")
print("TLB Unit Test Success")
+
if __name__ == "__main__":
test_tlb()
--- /dev/null
+/all.py
+/bcd.py
+/branch.py
+/comparefixed.py
+/condition.py
+/fixedarith.py
+/fixedload.py
+/fixedlogical.py
+/fixedshift.py
+/fixedstore.py
+/fixedtrap.py
+/sprset.py
+/stringldst.py
+/system.py
initial_regs[3] = 0x1234
initial_regs[2] = 0x4321
with Program(lst) as program:
- sim = self.run_test_program(program, initial_regs)
+ sim = self.run_tst_program(program, initial_regs)
self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
def test_addi(self):
"addi 2, 0, 0x4321",
"add 1, 3, 2"]
with Program(lst) as program:
- sim = self.run_test_program(program)
+ sim = self.run_tst_program(program)
print(sim.gpr(1))
self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
"stw 2, 0(1)",
"lwz 3, 0(1)"]
with Program(lst) as program:
- sim = self.run_test_program(program)
+ sim = self.run_tst_program(program)
print(sim.gpr(1))
self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
- def run_test_program(self, prog, initial_regs=[0] * 32):
+ def run_tst_program(self, prog, initial_regs=[0] * 32):
simulator = self.run_tst(prog, initial_regs)
simulator.gpr.dump()
return simulator
else:
ls = (lower, upper, step)
ls = ast.Tuple(ls)
- return ast.Call(ast.Name("selectassign"),
+ return ast.Call(ast.Name("selectassign", ast.Load()),
[left.value, ls, right], [])
else:
print("Assign fail")
print("func", node.func.id)
if node.func.id != 'concat':
return [node]
- if node.keywords: # a repeated list-constant, don't optimise
+ if node.keywords: # a repeated list-constant, don't optimise
return [node]
return node.args
# identify SelectableInt pattern [something] * N
# must return concat(something, repeat=N)
def identify_sint_mul_pattern(p):
- if p[2] != '*': # multiply
+ if p[2] != '*': # multiply
return False
- if not isinstance(p[3], ast.Constant): # rhs = Num
+ if not isinstance(p[3], ast.Constant): # rhs = Num
return False
- if not isinstance(p[1], ast.List): # lhs is a list
+ if not isinstance(p[1], ast.List): # lhs is a list
return False
l = p[1].elts
- if len(l) != 1: # lhs is a list of length 1
+ if len(l) != 1: # lhs is a list of length 1
return False
- return True # yippee!
+ return True # yippee!
def apply_trailer(atom, trailer):
# or Boolean OR
# lambda Lambda expression
+
class PowerParser:
precedence = (
def __init__(self, form):
self.gprs = {}
form = self.sd.sigforms[form]
- print (form)
+ print(form)
formkeys = form._asdict().keys()
for rname in ['RA', 'RB', 'RC', 'RT', 'RS']:
self.gprs[rname] = None
self.available_op_fields = set()
for k in formkeys:
if k not in self.gprs:
- if k == 'SPR': # sigh, lower-case to not conflict
+ if k == 'SPR': # sigh, lower-case to not conflict
k = k.lower()
self.available_op_fields.add(k)
self.op_fields = OrderedSet()
print(astor.dump_tree(p[1]))
# replace GPR(x) with GPR[x]
idx = p[1].args[0]
- p[1] = ast.Subscript(p[1].func, idx)
+ p[1] = ast.Subscript(p[1].func, idx, ast.Load())
elif isinstance(p[1], ast.Call) and p[1].func.id == 'MEM':
- print ("mem assign")
+ print("mem assign")
print(astor.dump_tree(p[1]))
- p[1].func.id = "memassign" # change function name to set
+ p[1].func.id = "memassign" # change function name to set
p[1].args.append(p[3])
p[0] = p[1]
- print ("mem rewrite")
+ print("mem rewrite")
print(astor.dump_tree(p[0]))
return
else:
- print ("help, help")
+ print("help, help")
print(astor.dump_tree(p[1]))
print("expr assign", name, p[1])
if name and name in self.gprs:
# auto-add-one (sigh) due to python range
start = p[4]
end = ast.BinOp(p[6], ast.Add(), ast.Constant(1))
- it = ast.Call(ast.Name("range"), [start, end], [])
+ it = ast.Call(ast.Name("range", ast.Load()), [start, end], [])
p[0] = ast.For(p[2], it, p[8], [])
def p_while_stmt(self, p):
print(astor.dump_tree(p[1]))
cases = []
- current_cases = [] # for deferral
+ current_cases = [] # for deferral
for (case, suite) in p[8]:
- print ("for", case, suite)
+ print("for", case, suite)
if suite is None:
for c in case:
current_cases.append(ast.Num(c))
continue
- if case == 'default': # last
+ if case == 'default': # last
break
for c in case:
current_cases.append(ast.Num(c))
- print ("cases", current_cases)
+ print("cases", current_cases)
compare = ast.Compare(switchon, [ast.In()],
- [ast.List(current_cases)])
+ [ast.List(current_cases, ast.Load())])
current_cases = []
cases.append((compare, suite))
- print ("ended", case, current_cases)
+ print("ended", case, current_cases)
if case == 'default':
if current_cases:
compare = ast.Compare(switchon, [ast.In()],
- [ast.List(current_cases)])
+ [ast.List(current_cases, ast.Load())])
cases.append((compare, suite))
cases.append((None, suite))
cases.reverse()
res = []
for compare, suite in cases:
- print ("after rev", compare, suite)
+ print("after rev", compare, suite)
if compare is None:
assert len(res) == 0, "last case should be default"
res = suite
if len(p) == 4:
print(list(p))
if p[2] == '<u':
- p[0] = ast.Call(ast.Name("ltu"), (p[1], p[3]), [])
+ p[0] = ast.Call(ast.Name("ltu", ast.Load()), (p[1], p[3]), [])
elif p[2] == '>u':
- p[0] = ast.Call(ast.Name("gtu"), (p[1], p[3]), [])
+ p[0] = ast.Call(ast.Name("gtu", ast.Load()), (p[1], p[3]), [])
elif p[2] == '||':
l = check_concat(p[1]) + check_concat(p[3])
- p[0] = ast.Call(ast.Name("concat"), l, [])
+ p[0] = ast.Call(ast.Name("concat", ast.Load()), l, [])
elif p[2] in ['<', '>', '=', '<=', '>=', '!=']:
p[0] = binary_ops[p[2]]((p[1], p[3]))
elif identify_sint_mul_pattern(p):
- keywords=[ast.keyword(arg='repeat', value=p[3])]
+ keywords = [ast.keyword(arg='repeat', value=p[3])]
l = p[1].elts
- p[0] = ast.Call(ast.Name("concat"), l, keywords)
+ p[0] = ast.Call(ast.Name("concat", ast.Load()), l, keywords)
else:
p[0] = ast.BinOp(p[1], binary_ops[p[2]], p[3])
elif len(p) == 3:
| test
"""
if len(p) == 2:
- p[0] = ast.List([p[1]])
+ p[0] = ast.List([p[1]], ast.Load())
else:
- p[0] = ast.List([p[1]] + p[3].nodes)
+ p[0] = ast.List([p[1]] + p[3].nodes, ast.Load())
def p_atom_tuple(self, p):
"""atom : LPAR testlist RPAR"""
print("tuple name", name)
if name in self.gprs:
self.read_regs.add(name) # add to list of regs to read
- #p[0] = ast.Subscript(ast.Name("GPR"), ast.Str(p[2].id))
+ #p[0] = ast.Subscript(ast.Name("GPR", ast.Load()), ast.Str(p[2].id))
# return
p[0] = p[2]
elif isinstance(p[2], ast.BinOp):
if isinstance(p[2].left, ast.Name) and \
isinstance(p[2].right, ast.Constant) and \
- p[2].right.value == 0 and \
- p[2].left.id in self.gprs:
- rid = p[2].left.id
- self.read_regs.add(rid) # add to list of regs to read
- # create special call to GPR.getz
- gprz = ast.Name("GPR")
- gprz = ast.Attribute(gprz, "getz") # get testzero function
- # *sigh* see class GPR. we need index itself not reg value
- ridx = ast.Name("_%s" % rid)
- p[0] = ast.Call(gprz, [ridx], [])
- print("tree", astor.dump_tree(p[0]))
+ p[2].right.value == 0 and \
+ p[2].left.id in self.gprs:
+ rid = p[2].left.id
+ self.read_regs.add(rid) # add to list of regs to read
+ # create special call to GPR.getz
+ gprz = ast.Name("GPR", ast.Load())
+ # get testzero function
+ gprz = ast.Attribute(gprz, "getz", ast.Load())
+ # *sigh* see class GPR. we need index itself not reg value
+ ridx = ast.Name("_%s" % rid, ast.Load())
+ p[0] = ast.Call(gprz, [ridx], [])
+ print("tree", astor.dump_tree(p[0]))
else:
p[0] = p[2]
else:
from nmutil.latch import SRLatch, latchregister
-from testmem import TestMemory
+from .testmem import TestMemory
# internal opcodes. hypothetically this could do more combinations.
# meanings:
# * bit 1: 0 = src1, 1 = IMM
# * bit 2: 1 = LD
# * bit 3: 1 = ST
-BIT0_ADD = 0
-BIT1_SRC = 1
-BIT2_ST = 2
-BIT3_LD = 3
+BIT0_ADD = 0
+BIT1_SRC = 1
+BIT2_ST = 2
+BIT3_LD = 3
# convenience thingies.
-LDST_OP_ADD = 0b0000 # plain ADD (src1 + src2) - use this ALU as an ADD
-LDST_OP_SUB = 0b0001 # plain SUB (src1 - src2) - use this ALU as a SUB
-LDST_OP_ADDI = 0b0010 # immed ADD (imm + src1)
-LDST_OP_SUBI = 0b0011 # immed SUB (imm - src1)
-LDST_OP_ST = 0b0110 # immed ADD plus LD op. ADD result is address
-LDST_OP_LD = 0b1010 # immed ADD plus ST op. ADD result is address
-
+LDST_OP_ADD = 0b0000 # plain ADD (src1 + src2) - use this ALU as an ADD
+LDST_OP_SUB = 0b0001 # plain SUB (src1 - src2) - use this ALU as a SUB
+LDST_OP_ADDI = 0b0010 # immed ADD (imm + src1)
+LDST_OP_SUBI = 0b0011 # immed SUB (imm - src1)
+LDST_OP_ST = 0b0110 # immed ADD plus LD op. ADD result is address
+LDST_OP_LD = 0b1010 # immed ADD plus ST op. ADD result is address
class LDSTCompUnit(Elaboratable):
* :data_o: Dest out (LD or ALU)
* :addr_o: Address out (LD or ST)
"""
+
def __init__(self, rwid, opwid, alu, mem):
self.opwid = opwid
self.rwid = rwid
self.mem = mem
self.counter = Signal(4)
- self.go_rd_i = Signal(reset_less=True) # go read in
- self.go_ad_i = Signal(reset_less=True) # go address in
- self.go_wr_i = Signal(reset_less=True) # go write in
- self.go_st_i = Signal(reset_less=True) # go store in
- self.issue_i = Signal(reset_less=True) # fn issue in
- self.isalu_i = Signal(reset_less=True) # fn issue as ALU in
- self.shadown_i = Signal(reset=1) # shadow function, defaults to ON
- self.go_die_i = Signal() # go die (reset)
-
- self.oper_i = Signal(opwid, reset_less=True) # opcode in
- self.imm_i = Signal(rwid, reset_less=True) # immediate in
- self.src1_i = Signal(rwid, reset_less=True) # oper1 in
- self.src2_i = Signal(rwid, reset_less=True) # oper2 in
+ self.go_rd_i = Signal(reset_less=True) # go read in
+ self.go_ad_i = Signal(reset_less=True) # go address in
+ self.go_wr_i = Signal(reset_less=True) # go write in
+ self.go_st_i = Signal(reset_less=True) # go store in
+ self.issue_i = Signal(reset_less=True) # fn issue in
+ self.isalu_i = Signal(reset_less=True) # fn issue as ALU in
+ self.shadown_i = Signal(reset=1) # shadow function, defaults to ON
+ self.go_die_i = Signal() # go die (reset)
+
+ self.oper_i = Signal(opwid, reset_less=True) # opcode in
+ self.imm_i = Signal(rwid, reset_less=True) # immediate in
+ self.src1_i = Signal(rwid, reset_less=True) # oper1 in
+ self.src2_i = Signal(rwid, reset_less=True) # oper2 in
self.busy_o = Signal(reset_less=True) # fn busy out
- self.rd_rel_o = Signal(reset_less=True) # request src1/src2
- self.adr_rel_o = Signal(reset_less=True) # request address (from mem)
- self.sto_rel_o = Signal(reset_less=True) # request store (to mem)
- self.req_rel_o = Signal(reset_less=True) # request write (result)
- self.done_o = Signal(reset_less=True) # final release signal
- self.data_o = Signal(rwid, reset_less=True) # Dest out (LD or ALU)
- self.addr_o = Signal(rwid, reset_less=True) # Address out (LD or ST)
+ self.rd_rel_o = Signal(reset_less=True) # request src1/src2
+ self.adr_rel_o = Signal(reset_less=True) # request address (from mem)
+ self.sto_rel_o = Signal(reset_less=True) # request store (to mem)
+ self.req_rel_o = Signal(reset_less=True) # request write (result)
+ self.done_o = Signal(reset_less=True) # final release signal
+ self.data_o = Signal(rwid, reset_less=True) # Dest out (LD or ALU)
+ self.addr_o = Signal(rwid, reset_less=True) # Address out (LD or ST)
# hmm... TODO... move these to outside of LDSTCompUnit?
- self.load_mem_o = Signal(reset_less=True) # activate memory LOAD
- self.stwd_mem_o = Signal(reset_less=True) # activate memory STORE
- self.ld_o = Signal(reset_less=True) # operation is a LD
- self.st_o = Signal(reset_less=True) # operation is a ST
+ self.load_mem_o = Signal(reset_less=True) # activate memory LOAD
+ self.stwd_mem_o = Signal(reset_less=True) # activate memory STORE
+ self.ld_o = Signal(reset_less=True) # operation is a LD
+ self.st_o = Signal(reset_less=True) # operation is a ST
def elaborate(self, platform):
m = Module()
reset_a = Signal(reset_less=True)
reset_s = Signal(reset_less=True)
reset_r = Signal(reset_less=True)
- comb += reset_b.eq(self.go_st_i|self.go_wr_i|self.go_ad_i|self.go_die_i)
+ comb += reset_b.eq(self.go_st_i | self.go_wr_i |
+ self.go_ad_i | self.go_die_i)
comb += reset_w.eq(self.go_wr_i | self.go_die_i)
comb += reset_s.eq(self.go_st_i | self.go_die_i)
comb += reset_r.eq(self.go_rd_i | self.go_die_i)
# this one is slightly different, issue_alu_i selects go_wr_i)
a_sel = Mux(self.isalu_i, self.go_wr_i, self.go_ad_i)
- comb += reset_a.eq(a_sel| self.go_die_i)
+ comb += reset_a.eq(a_sel | self.go_die_i)
# opcode decode
op_alu = Signal(reset_less=True)
# NOTE: use sync to stop combinatorial loops.
# opcode latch - inverted so that busy resets to 0
- sync += opc_l.s.eq(issue_i) # XXX NOTE: INVERTED FROM book!
- sync += opc_l.r.eq(reset_b) # XXX NOTE: INVERTED FROM book!
+ sync += opc_l.s.eq(issue_i) # XXX NOTE: INVERTED FROM book!
+ sync += opc_l.r.eq(reset_b) # XXX NOTE: INVERTED FROM book!
# src operand latch
sync += src_l.s.eq(issue_i)
sync += adr_l.r.eq(reset_a)
# dest operand latch
- sync += req_l.s.eq(self.go_ad_i|self.go_st_i|self.go_wr_i)
+ sync += req_l.s.eq(self.go_ad_i | self.go_st_i | self.go_wr_i)
sync += req_l.r.eq(reset_w)
# store latch
- sync += sto_l.s.eq(self.go_rd_i) # XXX not sure which
+ sync += sto_l.s.eq(self.go_rd_i) # XXX not sure which
sync += sto_l.r.eq(reset_s)
# outputs: busy and release signals
busy_o = self.busy_o
- comb += self.busy_o.eq(opc_l.q) # busy out
- comb += self.rd_rel_o.eq(src_l.q & busy_o) # src1/src2 req rel
+ comb += self.busy_o.eq(opc_l.q) # busy out
+ comb += self.rd_rel_o.eq(src_l.q & busy_o) # src1/src2 req rel
comb += self.sto_rel_o.eq(sto_l.q & busy_o & self.shadown_i & op_is_st)
# request release enabled based on if op is a LD/ST or a plain ALU
comb += wr_q.eq(req_l.q & (~op_ldst | op_is_ld))
alulatch = Signal(reset_less=True)
- comb += alulatch.eq((op_ldst & self.adr_rel_o) | \
+ comb += alulatch.eq((op_ldst & self.adr_rel_o) |
(~op_ldst & self.req_rel_o))
# select immediate if opcode says so. however also change the latch
latchregister(m, src2_or_imm, self.alu.b, src_sel, name="imm_r")
# create a latch/register for the operand
- oper_r = Signal(self.opwid, reset_less=True) # Dest register
+ oper_r = Signal(self.opwid, reset_less=True) # Dest register
latchregister(m, self.oper_i, oper_r, self.issue_i, name="operi_r")
- alu_op = Cat(op_alu, 0, op_is_imm) # using alu_hier, here.
+ alu_op = Cat(op_alu, 0, op_is_imm) # using alu_hier, here.
comb += self.alu.op.eq(alu_op)
# and one for the output from the ALU
- data_r = Signal(self.rwid, reset_less=True) # Dest register
+ data_r = Signal(self.rwid, reset_less=True) # Dest register
latchregister(m, self.alu.o, data_r, alulatch, "aluo_r")
# decode bits of operand (latched)
comb += op_alu.eq(oper_r[BIT0_ADD]) # ADD/SUB
- comb += op_is_imm.eq(oper_r[BIT1_SRC]) # IMMED/reg
+ comb += op_is_imm.eq(oper_r[BIT1_SRC]) # IMMED/reg
comb += op_is_st.eq(oper_r[BIT2_ST]) # OP is ST
comb += op_is_ld.eq(oper_r[BIT3_LD]) # OP is LD
comb += op_ldst.eq(op_is_ld | op_is_st)
# go_read is only valid for one clock!
with m.If(self.go_rd_i): # src operands ready, GO!
with m.If(~self.alu.p_ready_o): # no ACK yet
- m.d.comb += self.alu.p_valid_i.eq(1) # so indicate valid
+ m.d.comb += self.alu.p_valid_i.eq(1) # so indicate valid
# only proceed if ALU says its output is valid
with m.If(self.alu.n_valid_o):
# write req release out. waits until shadow is dropped.
comb += self.req_rel_o.eq(wr_q & busy_o & self.shadown_i)
# address release only happens on LD/ST, and is shadowed.
- comb += self.adr_rel_o.eq(adr_l.q & op_ldst & busy_o & \
+ comb += self.adr_rel_o.eq(adr_l.q & op_ldst & busy_o &
self.shadown_i)
# when output latch is ready, and ALU says ready, accept ALU output
with m.If(self.req_rel_o):
- m.d.comb += self.alu.n_ready_i.eq(1) # tells ALU "thanks got it"
+ # tells ALU "thanks got it"
+ m.d.comb += self.alu.n_ready_i.eq(1)
# provide "done" signal: select req_rel for non-LD/ST, adr_rel for LD/ST
comb += self.done_o.eq((self.req_rel_o & ~op_ldst) |
def ports(self):
return list(self)
+
def wait_for(sig):
v = (yield sig)
- print ("wait for", sig, v)
+ print("wait for", sig, v)
while True:
yield
v = (yield sig)
- print (v)
+ print(v)
if v:
break
+
def store(dut, src1, src2, imm):
yield dut.oper_i.eq(LDST_OP_ST)
yield dut.src1_i.eq(src1)
yield
data = (yield dut.data_o)
yield dut.go_ad_i.eq(0)
- #wait_for(dut.stwd_mem_o)
+ # wait_for(dut.stwd_mem_o)
return data
-def add(dut, src1, src2, imm, imm_mode = False):
+def add(dut, src1, src2, imm, imm_mode=False):
yield dut.oper_i.eq(LDST_OP_ADDI if imm_mode else LDST_OP_ADD)
yield dut.src1_i.eq(src1)
yield dut.src2_i.eq(src2)
data = (yield dut.data_o)
yield dut.go_wr_i.eq(0)
yield
- #wait_for(dut.stwd_mem_o)
+ # wait_for(dut.stwd_mem_o)
return data
+
def scoreboard_sim(dut):
# two STs (different addresses)
yield from store(dut, 4, 3, 2)
run_simulation(dut, scoreboard_sim(dut), vcd_name='test_ldst_comp.vcd')
+
if __name__ == '__main__':
test_scoreboard()
self.fpregs = RegFileArray(rwid, n_regs)
# inputs
- self.int_store_i = Signal(reset_less=True) # instruction is a store
- self.int_dest_i = Signal(max=n_regs, reset_less=True) # Dest R# in
- self.int_src1_i = Signal(max=n_regs, reset_less=True) # oper1 R# in
- self.int_src2_i = Signal(max=n_regs, reset_less=True) # oper2 R# in
+ self.int_store_i = Signal(reset_less=True) # instruction is a store
+ self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
+ self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
+ self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
- self.issue_o = Signal(reset_less=True) # instruction was accepted
+ self.issue_o = Signal(reset_less=True) # instruction was accepted
def elaborate(self, platform):
m = Module()
m.submodules.comp2 = comp2 = ComputationUnitNoDelay(self.rwid, 1, sub)
int_alus = [comp1, comp2]
- m.d.comb += comp1.oper_i.eq(Const(0)) # temporary/experiment: op=add
- m.d.comb += comp2.oper_i.eq(Const(1)) # temporary/experiment: op=sub
+ m.d.comb += comp1.oper_i.eq(Const(0)) # temporary/experiment: op=add
+ m.d.comb += comp2.oper_i.eq(Const(1)) # temporary/experiment: op=sub
# Int FUs
if_l = []
# Count of number of FUs
n_int_fus = len(if_l)
- n_fp_fus = 0 # for now
+ n_fp_fus = 0 # for now
- n_fus = n_int_fus + n_fp_fus # plus FP FUs
+ n_fus = n_int_fus + n_fp_fus # plus FP FUs
# XXX replaced by array of FUs? *FnUnit
# # Integer FU-FU Dep Matrix
# m.submodules.intregdeps = intregdeps
# Integer Priority Picker 1: Adder + Subtractor
- intpick1 = GroupPicker(2) # picks between add and sub
+ intpick1 = GroupPicker(2) # picks between add and sub
m.submodules.intpick1 = intpick1
# Global Pending Vectors (INT and FP)
intfudeps = FUFUDepMatrix(n_int_fus, n_int_fus)
m.submodules.intfudeps = intfudeps
- #---------
+ # ---------
# ok start wiring things together...
# "now hear de word of de looord... dem bones dem bones dem dryy bones"
# https://www.youtube.com/watch?v=pYb8Wm6-QfA
- #---------
+ # ---------
- #---------
+ # ---------
# Issue Unit is where it starts. set up some in/outs for this module
- #---------
+ # ---------
m.d.comb += [issueunit.i.store_i.eq(self.int_store_i),
regdecode.dest_i.eq(self.int_dest_i),
regdecode.src1_i.eq(self.int_src1_i),
regdecode.src2_i.eq(self.int_src2_i),
regdecode.enable_i.eq(1),
self.issue_o.eq(issueunit.issue_o),
- issueunit.i.dest_i.eq(regdecode.dest_o),
- ]
- self.int_insn_i = issueunit.i.insn_i # enabled by instruction decode
+ issueunit.i.dest_i.eq(regdecode.dest_o),
+ ]
+ self.int_insn_i = issueunit.i.insn_i # enabled by instruction decode
# connect global rd/wr pending vectors
m.d.comb += issueunit.i.g_wr_pend_i.eq(g_int_wr_pend_v.g_pend_o)
# XXX sync, so as to stop a simulation infinite loop
m.d.comb += issueunit.i.busy_i[i].eq(fu.busy_o)
- #---------
+ # ---------
# connect Function Units
- #---------
+ # ---------
# Group Picker... done manually for now. TODO: cat array of pick sigs
- m.d.comb += if_l[0].go_rd_i.eq(intpick1.go_rd_o[0]) # add rd
- m.d.comb += if_l[0].go_wr_i.eq(intpick1.go_wr_o[0]) # add wr
+ m.d.comb += if_l[0].go_rd_i.eq(intpick1.go_rd_o[0]) # add rd
+ m.d.comb += if_l[0].go_wr_i.eq(intpick1.go_wr_o[0]) # add wr
- m.d.comb += if_l[1].go_rd_i.eq(intpick1.go_rd_o[1]) # subtract rd
- m.d.comb += if_l[1].go_wr_i.eq(intpick1.go_wr_o[1]) # subtract wr
+ m.d.comb += if_l[1].go_rd_i.eq(intpick1.go_rd_o[1]) # subtract rd
+ m.d.comb += if_l[1].go_wr_i.eq(intpick1.go_wr_o[1]) # subtract wr
# create read-pending FU-FU vectors
- intfu_rd_pend_v = Signal(n_int_fus, reset_less = True)
- intfu_wr_pend_v = Signal(n_int_fus, reset_less = True)
+ intfu_rd_pend_v = Signal(n_int_fus, reset_less=True)
+ intfu_wr_pend_v = Signal(n_int_fus, reset_less=True)
for i in range(n_int_fus):
#m.d.comb += intfu_rd_pend_v[i].eq(if_l[i].int_rd_pend_o.bool())
#m.d.comb += intfu_wr_pend_v[i].eq(if_l[i].int_wr_pend_o.bool())
m.d.comb += intfudeps.go_wr_i[i].eq(intpick1.go_wr_o[i])
# Connect Picker (note connection to FU-FU)
- #---------
+ # ---------
readable_o = intfudeps.readable_o
writable_o = intfudeps.writable_o
m.d.comb += intpick1.rd_rel_i[0].eq(int_alus[0].rd_rel_o)
m.d.comb += intpick1.rd_rel_i[1].eq(int_alus[1].rd_rel_o)
m.d.comb += intpick1.req_rel_i[0].eq(int_alus[0].req_rel_o)
m.d.comb += intpick1.req_rel_i[1].eq(int_alus[1].req_rel_o)
- m.d.comb += intpick1.readable_i[0].eq(readable_o[0]) # add rd
- m.d.comb += intpick1.writable_i[0].eq(writable_o[0]) # add wr
- m.d.comb += intpick1.readable_i[1].eq(readable_o[1]) # sub rd
- m.d.comb += intpick1.writable_i[1].eq(writable_o[1]) # sub wr
+ m.d.comb += intpick1.readable_i[0].eq(readable_o[0]) # add rd
+ m.d.comb += intpick1.writable_i[0].eq(writable_o[0]) # add wr
+ m.d.comb += intpick1.readable_i[1].eq(readable_o[1]) # sub rd
+ m.d.comb += intpick1.writable_i[1].eq(writable_o[1]) # sub wr
- #---------
+ # ---------
# Connect Register File(s)
- #---------
- #with m.If(if_l[0].go_wr_i | if_l[1].go_wr_i):
+ # ---------
+ # with m.If(if_l[0].go_wr_i | if_l[1].go_wr_i):
m.d.sync += int_dest.wen.eq(g_int_wr_pend_v.g_pend_o)
- #with m.If(intpick1.go_rd_o):
- #with m.If(if_l[0].go_rd_i | if_l[1].go_rd_i):
+ # with m.If(intpick1.go_rd_o):
+ # with m.If(if_l[0].go_rd_i | if_l[1].go_rd_i):
m.d.sync += int_src1.ren.eq(g_int_src1_pend_v.g_pend_o)
m.d.sync += int_src2.ren.eq(g_int_src2_pend_v.g_pend_o)
m.d.comb += alu.go_rd_i.eq(intpick1.go_rd_o[i])
m.d.comb += alu.go_wr_i.eq(intpick1.go_wr_o[i])
m.d.comb += alu.issue_i.eq(fn_issue_l[i])
- #m.d.comb += fn_busy_l[i].eq(alu.busy_o) # XXX ignore, use fnissue
+ # m.d.comb += fn_busy_l[i].eq(alu.busy_o) # XXX ignore, use fnissue
m.d.comb += alu.src1_i.eq(int_src1.data_o)
m.d.comb += alu.src2_i.eq(int_src2.data_o)
- m.d.comb += if_l[i].req_rel_i.eq(alu.req_rel_o) # pipe out ready
+ m.d.comb += if_l[i].req_rel_i.eq(alu.req_rel_o) # pipe out ready
return m
-
def __iter__(self):
yield from self.intregs
yield from self.fpregs
yield self.int_src1_i
yield self.int_src2_i
yield self.issue_o
- #yield from self.int_src1
- #yield from self.int_dest
- #yield from self.int_src1
- #yield from self.int_src2
- #yield from self.fp_dest
- #yield from self.fp_src1
- #yield from self.fp_src2
+ # yield from self.int_src1
+ # yield from self.int_dest
+ # yield from self.int_src1
+ # yield from self.int_src2
+ # yield from self.fp_dest
+ # yield from self.fp_src1
+ # yield from self.fp_src2
def ports(self):
return list(self)
+
IADD = 0
ISUB = 1
+
class RegSim:
def __init__(self, rwidth, nregs):
self.rwidth = rwidth
src1 = self.regs[src1]
src2 = self.regs[src2]
if op == IADD:
- val = (src1 + src2) & ((1<<(self.rwidth))-1)
+ val = (src1 + src2) & ((1 << (self.rwidth))-1)
elif op == ISUB:
- val = (src1 - src2) & ((1<<(self.rwidth))-1)
+ val = (src1 - src2) & ((1 << (self.rwidth))-1)
self.regs[dest] = val
def setval(self, dest, val):
yield from self.dump(dut)
assert False
+
def int_instr(dut, alusim, op, src1, src2, dest):
for i in range(len(dut.int_insn_i)):
yield dut.int_insn_i[i].eq(0)
reg = yield dut.intregs.regs[rnum].reg
rs.append("%x" % reg)
rnums = map(str, rnums)
- print ("reg %s: %s" % (','.join(rnums), ','.join(rs)))
+ print("reg %s: %s" % (','.join(rnums), ','.join(rs)))
def scoreboard_sim(dut, alusim):
if False:
yield from int_instr(dut, alusim, IADD, 4, 3, 5)
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
yield from int_instr(dut, alusim, IADD, 5, 2, 5)
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
yield from int_instr(dut, alusim, ISUB, 5, 1, 3)
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
for i in range(len(dut.int_insn_i)):
yield dut.int_insn_i[i].eq(0)
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
yield from alusim.check(dut)
#op = (i+1) % 2
op = i
- print ("random %d: %d %d %d %d\n" % (i, op, src1, src2, dest))
+ print("random %d: %d %d %d %d\n" % (i, op, src1, src2, dest))
yield from int_instr(dut, alusim, op, src1, src2, dest)
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
while True:
yield
issue_o = yield dut.issue_o
if issue_o:
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
for i in range(len(dut.int_insn_i)):
yield dut.int_insn_i[i].eq(0)
break
- print ("busy",)
- yield from print_reg(dut, [3,4,5])
+ print("busy",)
+ yield from print_reg(dut, [3, 4, 5])
yield
yield
yield
-
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
- yield from print_reg(dut, [3,4,5])
+ yield from print_reg(dut, [3, 4, 5])
yield
yield
yield
groups = LHSGroupAnalyzer()(fragment._statements)
- print (groups)
+ print(groups)
def test_scoreboard():
f.write(vl)
run_simulation(dut, scoreboard_sim(dut, alusim),
- vcd_name='test_scoreboard.vcd')
+ vcd_name='test_scoreboard.vcd')
if __name__ == '__main__':
from soc.scoreboard.instruction_q import Instruction, InstructionQ
from soc.scoreboard.memfu import MemFunctionUnits
-from compalu import ComputationUnitNoDelay
-from compldst import LDSTCompUnit
-from testmem import TestMemory
+from .compalu import ComputationUnitNoDelay
+from .compldst import LDSTCompUnit
+from .testmem import TestMemory
-from alu_hier import ALU, BranchALU
+from .alu_hier import ALU, BranchALU
from nmutil.latch import SRLatch
from nmutil.nmoperator import eq
Computation Unit" as defined by Mitch Alsup (see section
11.4.9.3)
"""
+
def __init__(self, rwid, units, ldstmode=False):
""" Inputs:
self.req_rel_o = Signal(n_units, reset_less=True)
self.done_o = Signal(n_units, reset_less=True)
if ldstmode:
- self.ld_o = Signal(n_units, reset_less=True) # op is LD
- self.st_o = Signal(n_units, reset_less=True) # op is ST
+ self.ld_o = Signal(n_units, reset_less=True) # op is LD
+ self.st_o = Signal(n_units, reset_less=True) # op is ST
self.adr_rel_o = Signal(n_units, reset_less=True)
self.sto_rel_o = Signal(n_units, reset_less=True)
self.load_mem_o = Signal(n_units, reset_less=True)
units = []
for alu in self.alus:
- aluopwid = 4 # see compldst.py for "internal" opcode
+ aluopwid = 4 # see compldst.py for "internal" opcode
units.append(LDSTCompUnit(rwid, aluopwid, alu, mem))
CompUnitsBase.__init__(self, rwid, units, ldstmode=True)
units = []
for alu in alus:
- aluopwid = 3 # extra bit for immediate mode
+ aluopwid = 3 # extra bit for immediate mode
units.append(ComputationUnitNoDelay(rwid, aluopwid, alu))
CompUnitsBase.__init__(self, rwid, units)
# Branch ALU and CU
self.bgt = BranchALU(rwid)
- aluopwid = 3 # extra bit for immediate mode
+ aluopwid = 3 # extra bit for immediate mode
self.br1 = ComputationUnitNoDelay(rwid, aluopwid, self.bgt)
CompUnitsBase.__init__(self, rwid, [self.br1])
self.n_regs = n_regs
self.n_int_alus = n_int_alus
- self.dest_i = Signal(n_regs, reset_less=True) # Dest R# in
- self.src1_i = Signal(n_regs, reset_less=True) # oper1 R# in
- self.src2_i = Signal(n_regs, reset_less=True) # oper2 R# in
+ self.dest_i = Signal(n_regs, reset_less=True) # Dest R# in
+ self.src1_i = Signal(n_regs, reset_less=True) # oper1 R# in
+ self.src2_i = Signal(n_regs, reset_less=True) # oper2 R# in
self.g_int_rd_pend_o = Signal(n_regs, reset_less=True)
self.g_int_wr_pend_o = Signal(n_regs, reset_less=True)
- self.dest_rsel_o = Signal(n_regs, reset_less=True) # dest reg (bot)
- self.src1_rsel_o = Signal(n_regs, reset_less=True) # src1 reg (bot)
- self.src2_rsel_o = Signal(n_regs, reset_less=True) # src2 reg (bot)
+ self.dest_rsel_o = Signal(n_regs, reset_less=True) # dest reg (bot)
+ self.src1_rsel_o = Signal(n_regs, reset_less=True) # src1 reg (bot)
+ self.src2_rsel_o = Signal(n_regs, reset_less=True) # src2 reg (bot)
self.readable_o = Signal(n_int_alus, reset_less=True)
self.writable_o = Signal(n_int_alus, reset_less=True)
comb += intfudeps.rd_pend_i.eq(intregdeps.rd_pend_o)
comb += intfudeps.wr_pend_i.eq(intregdeps.wr_pend_o)
- self.wr_pend_o = intregdeps.wr_pend_o # also output for use in WaWGrid
+ self.wr_pend_o = intregdeps.wr_pend_o # also output for use in WaWGrid
comb += intfudeps.issue_i.eq(self.fn_issue_i)
comb += intfudeps.go_rd_i.eq(self.go_rd_i)
self.fpregs = RegFileArray(rwid, n_regs)
# Memory (test for now)
- self.mem = TestMemory(self.rwid, 8) # not too big, takes too long
+ self.mem = TestMemory(self.rwid, 8) # not too big, takes too long
# issue q needs to get at these
self.aluissue = IssueUnitGroup(2)
self.ls_imm_i = Signal(rwid, reset_less=True)
# inputs
- self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
- self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
- self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
- self.reg_enable_i = Signal(reset_less=True) # enable reg decode
+ self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
+ self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
+ self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
+ self.reg_enable_i = Signal(reset_less=True) # enable reg decode
# outputs
- self.issue_o = Signal(reset_less=True) # instruction was accepted
- self.busy_o = Signal(reset_less=True) # at least one CU is busy
+ self.issue_o = Signal(reset_less=True) # instruction was accepted
+ self.busy_o = Signal(reset_less=True) # at least one CU is busy
# for branch speculation experiment. branch_direction = 0 if
# the branch hasn't been met yet. 1 indicates "success", 2 is "fail"
# Int ALUs and BR ALUs
n_int_alus = 5
cua = CompUnitALUs(self.rwid, 3, n_alus=self.aluissue.n_insns)
- cub = CompUnitBR(self.rwid, 3) # 1 BR ALUs
+ cub = CompUnitBR(self.rwid, 3) # 1 BR ALUs
# LDST Comp Units
n_ldsts = 2
# Comp Units
m.submodules.cu = cu = CompUnitsBase(self.rwid, [cua, cul, cub])
- bgt = cub.bgt # get at the branch computation unit
+ bgt = cub.bgt # get at the branch computation unit
br1 = cub.br1
# Int FUs
m.submodules.memfus = memfus = MemFunctionUnits(n_ldsts, 5)
# Memory Priority Picker 1: one gateway per memory port
- mempick1 = GroupPicker(n_ldsts) # picks 1 reader and 1 writer to intreg
+ # picks 1 reader and 1 writer to intreg
+ mempick1 = GroupPicker(n_ldsts)
m.submodules.mempick1 = mempick1
# Count of number of FUs
n_intfus = n_int_alus
- n_fp_fus = 0 # for now
+ n_fp_fus = 0 # for now
# Integer Priority Picker 1: Adder + Subtractor (and LD/ST)
- intpick1 = GroupPicker(n_intfus) # picks 1 reader and 1 writer to intreg
+ # picks 1 reader and 1 writer to intreg
+ intpick1 = GroupPicker(n_intfus)
m.submodules.intpick1 = intpick1
# INT/FP Issue Unit
# allow/cancel can be issued as appropriate.
m.submodules.specrec = bspec = BranchSpeculationRecord(n_intfus)
- #---------
+ # ---------
# ok start wiring things together...
# "now hear de word of de looord... dem bones dem bones dem dryy bones"
# https://www.youtube.com/watch?v=pYb8Wm6-QfA
- #---------
+ # ---------
- #---------
+ # ---------
# Issue Unit is where it starts. set up some in/outs for this module
- #---------
- comb += [ regdecode.dest_i.eq(self.int_dest_i),
- regdecode.src1_i.eq(self.int_src1_i),
- regdecode.src2_i.eq(self.int_src2_i),
- regdecode.enable_i.eq(self.reg_enable_i),
- self.issue_o.eq(issueunit.issue_o)
- ]
+ # ---------
+ comb += [regdecode.dest_i.eq(self.int_dest_i),
+ regdecode.src1_i.eq(self.int_src1_i),
+ regdecode.src2_i.eq(self.int_src2_i),
+ regdecode.enable_i.eq(self.reg_enable_i),
+ self.issue_o.eq(issueunit.issue_o)
+ ]
# take these to outside (issue needs them)
comb += cua.oper_i.eq(self.alu_oper_i)
comb += issueunit.busy_i.eq(cu.busy_o)
comb += self.busy_o.eq(cu.busy_o.bool())
- #---------
+ # ---------
# Memory Function Unit
- #---------
+ # ---------
reset_b = Signal(cul.n_units, reset_less=True)
sync += reset_b.eq(cul.go_st_i | cul.go_wr_i | cul.go_die_i)
- comb += memfus.fn_issue_i.eq(cul.issue_i) # Comp Unit Issue -> Mem FUs
- comb += memfus.addr_en_i.eq(cul.adr_rel_o) # Match enable on adr rel
- comb += memfus.addr_rs_i.eq(reset_b) # reset same as LDSTCompUnit
+ comb += memfus.fn_issue_i.eq(cul.issue_i) # Comp Unit Issue -> Mem FUs
+ comb += memfus.addr_en_i.eq(cul.adr_rel_o) # Match enable on adr rel
+ comb += memfus.addr_rs_i.eq(reset_b) # reset same as LDSTCompUnit
# LD/STs have to accumulate prior LD/STs (TODO: multi-issue as well,
# in a transitive fashion). This cycle activates based on LDSTCompUnit
# issue_i. multi-issue gets a bit more complex but not a lot.
prior_ldsts = Signal(cul.n_units, reset_less=True)
sync += prior_ldsts.eq(memfus.g_int_ld_pend_o | memfus.g_int_st_pend_o)
- with m.If(self.ls_oper_i[3]): # LD bit of operand
+ with m.If(self.ls_oper_i[3]): # LD bit of operand
comb += memfus.ld_i.eq(cul.issue_i | prior_ldsts)
- with m.If(self.ls_oper_i[2]): # ST bit of operand
+ with m.If(self.ls_oper_i[2]): # ST bit of operand
comb += memfus.st_i.eq(cul.issue_i | prior_ldsts)
# TODO: adr_rel_o needs to go into L1 Cache. for now,
# XXX should only be done when the memory ld/st has actually happened!
go_st_i = Signal(cul.n_units, reset_less=True)
go_ld_i = Signal(cul.n_units, reset_less=True)
- comb += go_ld_i.eq(memfus.loadable_o & memfus.addr_nomatch_o &\
- cul.adr_rel_o & cul.ld_o)
- comb += go_st_i.eq(memfus.storable_o & memfus.addr_nomatch_o &\
- cul.sto_rel_o & cul.st_o)
+ comb += go_ld_i.eq(memfus.loadable_o & memfus.addr_nomatch_o &
+ cul.adr_rel_o & cul.ld_o)
+ comb += go_st_i.eq(memfus.storable_o & memfus.addr_nomatch_o &
+ cul.sto_rel_o & cul.st_o)
comb += memfus.go_ld_i.eq(go_ld_i)
comb += memfus.go_st_i.eq(go_st_i)
#comb += cul.go_wr_i.eq(go_ld_i)
#comb += cu.go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus])
#comb += cu.issue_i[0:n_intfus].eq(fn_issue_o[0:n_intfus])
- #---------
+ # ---------
# merge shadow matrices outputs
- #---------
+ # ---------
# these are explained in ShadowMatrix docstring, and are to be
# connected to the FUReg and FUFU Matrices, to get them to reset
comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o)
comb += shreset.eq(bspec.match_g_o | bspec.match_f_o)
- #---------
+ # ---------
# connect fu-fu matrix
- #---------
+ # ---------
# Group Picker... done manually for now.
go_rd_o = intpick1.go_rd_o
go_wr_i = intfus.go_wr_i
go_die_i = intfus.go_die_i
# NOTE: connect to the shadowed versions so that they can "die" (reset)
- comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
- comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
- comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
+ comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
+ comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
+ comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
# Connect Picker
- #---------
+ # ---------
comb += intpick1.rd_rel_i[0:n_intfus].eq(cu.rd_rel_o[0:n_intfus])
comb += intpick1.req_rel_i[0:n_intfus].eq(cu.done_o[0:n_intfus])
int_rd_o = intfus.readable_o
comb += intpick1.readable_i[0:n_intfus].eq(int_rd_o[0:n_intfus])
comb += intpick1.writable_i[0:n_intfus].eq(int_wr_o[0:n_intfus])
- #---------
+ # ---------
# Shadow Matrix
- #---------
+ # ---------
comb += shadows.issue_i.eq(fn_issue_o)
#comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
- #---------
+ # ---------
# NOTE; this setup is for the instruction order preservation...
# connect shadows / go_dies to Computation Units
for i in range(n_intfus):
comb += shadows.shadow_i[i][0:n_intfus].eq(prev_shadow)
- #---------
+ # ---------
# ... and this is for branch speculation. it uses the extra bit
# tacked onto the ShadowMatrix (hence shadow_wid=n_intfus+1)
# only needs to set shadow_i, s_fail_i and s_good_i
with m.If(bactive & (self.branch_succ_i | self.branch_fail_i)):
comb += bshadow.issue_i.eq(fn_issue_o)
for i in range(n_intfus):
- with m.If(fn_issue_o & (Const(1<<i))):
+ with m.If(fn_issue_o & (Const(1 << i))):
comb += bshadow.shadow_i[i][0].eq(1)
# finally, we need an indicator to the test infrastructure as to
with m.If(br1.issue_i):
sync += bspec.active_i.eq(1)
with m.If(self.branch_succ_i):
- comb += bspec.good_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT
+ comb += bspec.good_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT
with m.If(self.branch_fail_i):
- comb += bspec.fail_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT
+ comb += bspec.fail_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT
# branch is active (TODO: a better signal: this is over-using the
# go_write signal - actually the branch should not be "writing")
# ... or it didn't
comb += bshadow.s_fail_i[i][0].eq(bspec.match_f_o[i])
- #---------
+ # ---------
# Connect Register File(s)
- #---------
+ # ---------
comb += int_dest.wen.eq(intfus.dest_rsel_o)
comb += int_src1.ren.eq(intfus.src1_rsel_o)
comb += int_src2.ren.eq(intfus.src2_rsel_o)
self.n_regs = n_regs
mqbits = unsigned(int(log(qlen) / log(2))+2)
- self.p_add_i = Signal(mqbits) # instructions to add (from data_i)
- self.p_ready_o = Signal() # instructions were added
+ self.p_add_i = Signal(mqbits) # instructions to add (from data_i)
+ self.p_ready_o = Signal() # instructions were added
self.data_i = Instruction.nq(n_in, "data_i", rwid, opwid)
- self.busy_o = Signal(reset_less=True) # at least one CU is busy
+ self.busy_o = Signal(reset_less=True) # at least one CU is busy
self.qlen_o = Signal(mqbits, reset_less=True)
def elaborate(self, platform):
comb = m.d.comb
sync = m.d.sync
- iq = InstructionQ(self.rwid, self.opw, self.qlen, self.n_in, self.n_out)
+ iq = InstructionQ(self.rwid, self.opw, self.qlen,
+ self.n_in, self.n_out)
sc = Scoreboard(self.rwid, self.n_regs)
m.submodules.iq = iq
m.submodules.sc = sc
src1 = iq.data_o[0].src1_i
src2 = iq.data_o[0].src2_i
op = iq.data_o[0].oper_i
- opi = iq.data_o[0].opim_i # immediate set
+ opi = iq.data_o[0].opim_i # immediate set
# set the src/dest regs
comb += sc.int_dest_i.eq(dest)
comb += sc.int_src1_i.eq(src1)
comb += sc.int_src2_i.eq(src2)
- comb += sc.reg_enable_i.eq(1) # enable the regfile
+ comb += sc.reg_enable_i.eq(1) # enable the regfile
# choose a Function-Unit-Group
- with m.If((op & (0x3<<2)) != 0): # branch
+ with m.If((op & (0x3 << 2)) != 0): # branch
comb += sc.br_oper_i.eq(Cat(op[0:2], opi))
comb += sc.br_imm_i.eq(imm)
comb += sc.brissue.insn_i.eq(1)
comb += wait_issue_br.eq(1)
- with m.Elif((op & (0x3<<4)) != 0): # ld/st
+ with m.Elif((op & (0x3 << 4)) != 0): # ld/st
# see compldst.py
# bit 0: ADD/SUB
# bit 1: immed
comb += sc.ls_imm_i.eq(imm)
comb += sc.lsissue.insn_i.eq(1)
comb += wait_issue_ls.eq(1)
- with m.Else(): # alu
+ with m.Else(): # alu
comb += sc.alu_oper_i.eq(Cat(op[0:2], opi))
comb += sc.alu_imm_i.eq(imm)
comb += sc.aluissue.insn_i.eq(1)
# these indicate that the instruction is to be made
# shadow-dependent on
# (either) branch success or branch fail
- #yield sc.branch_fail_i.eq(branch_fail)
- #yield sc.branch_succ_i.eq(branch_success)
+ # yield sc.branch_fail_i.eq(branch_fail)
+ # yield sc.branch_succ_i.eq(branch_success)
return m
for idx in range(sendlen):
yield from eq(dut.data_i[idx], instrs[idx])
di = yield dut.data_i[idx]
- print ("senddata %d %x" % (idx, di))
+ print("senddata %d %x" % (idx, di))
yield dut.p_add_i.eq(sendlen)
yield
o_p_ready = yield dut.p_ready_o
yield dut.int_dest_i.eq(dest)
yield dut.int_src1_i.eq(src1)
yield dut.int_src2_i.eq(src2)
- if (op & (0x3<<2)) != 0: # branch
+ if (op & (0x3 << 2)) != 0: # branch
yield dut.brissue.insn_i.eq(1)
yield dut.br_oper_i.eq(Const(op & 0x3, 2))
yield dut.br_imm_i.eq(imm)
reg = yield dut.intregs.regs[rnum].reg
rs.append("%x" % reg)
rnums = map(str, rnums)
- print ("reg %s: %s" % (','.join(rnums), ','.join(rs)))
+ print("reg %s: %s" % (','.join(rnums), ','.join(rs)))
def create_random_ops(dut, n_ops, shadowing=False, max_opnums=3):
for i in range(n_ops):
src1 = randint(1, dut.n_regs-1)
src2 = randint(1, dut.n_regs-1)
- imm = randint(1, (1<<dut.rwid)-1)
+ imm = randint(1, (1 << dut.rwid)-1)
dest = randint(1, dut.n_regs-1)
op = randint(0, max_opnums)
- opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
+ opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
if shadowing:
insts.append((src1, src2, dest, op, opi, imm, (0, 0)))
busy_o = yield dut.busy_o
if not busy_o:
break
- print ("busy",)
+ print("busy",)
yield
+
def disable_issue(dut):
yield dut.aluissue.insn_i.eq(0)
yield dut.brissue.insn_i.eq(0)
yield from disable_issue(dut)
yield dut.reg_enable_i.eq(0)
break
- print ("busy",)
- #yield from print_reg(dut, [1,2,3])
+ print("busy",)
+ # yield from print_reg(dut, [1,2,3])
yield
- #yield from print_reg(dut, [1,2,3])
+ # yield from print_reg(dut, [1,2,3])
+
def scoreboard_branch_sim(dut, alusim):
for i in range(1):
- print ("rseed", iseed)
+ print("rseed", iseed)
seed(iseed)
iseed += 1
# set random values in the registers
for i in range(1, dut.n_regs):
val = 31+i*3
- val = randint(0, (1<<alusim.rwidth)-1)
+ val = randint(0, (1 << alusim.rwidth)-1)
yield dut.intregs.regs[i].reg.eq(val)
alusim.setval(i, val)
src1 = randint(1, dut.n_regs-1)
src2 = randint(1, dut.n_regs-1)
#op = randint(4, 7)
- op = 4 # only BGT at the moment
+ op = 4 # only BGT at the moment
branch_ok = create_random_ops(dut, 1, True, 1)
branch_fail = create_random_ops(dut, 1, True, 1)
if True:
insts = []
- insts.append( (3, 5, 2, 0, (0, 0)) )
+ insts.append((3, 5, 2, 0, (0, 0)))
branch_ok = []
branch_fail = []
#branch_ok.append ( (5, 7, 5, 1, (1, 0)) )
- branch_ok.append( None )
- branch_fail.append( (1, 1, 2, 0, (0, 1)) )
+ branch_ok.append(None)
+ branch_fail.append((1, 1, 2, 0, (0, 1)))
#branch_fail.append( None )
- insts.append( (6, 4, (branch_ok, branch_fail), 4, (0, 0)) )
+ insts.append((6, 4, (branch_ok, branch_fail), 4, (0, 0)))
siminsts = deepcopy(insts)
yield
yield
i += 1
- branch_direction = yield dut.branch_direction_o # way branch went
+ branch_direction = yield dut.branch_direction_o # way branch went
(src1, src2, dest, op, (shadow_on, shadow_off)) = insts.pop(0)
if branch_direction == 1 and shadow_on:
- print ("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
- continue # branch was "success" and this is a "failed"... skip
+ print("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
+ continue # branch was "success" and this is a "failed"... skip
if branch_direction == 2 and shadow_off:
- print ("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
- continue # branch was "fail" and this is a "success"... skip
+ print("skip", i, src1, src2, dest, op, shadow_on, shadow_off)
+ continue # branch was "fail" and this is a "success"... skip
if branch_direction != 0:
shadow_on = 0
shadow_off = 0
instrs.append((ok[0], ok[1], ok[2], ok[3], (1, 0)))
if fl:
instrs.append((fl[0], fl[1], fl[2], fl[3], (0, 1)))
- print ("instr %d: (%d, %d, %d, %d, (%d, %d))" % \
- (i, src1, src2, dest, op, shadow_on, shadow_off))
+ print("instr %d: (%d, %d, %d, %d, (%d, %d))" %
+ (i, src1, src2, dest, op, shadow_on, shadow_off))
yield from int_instr(dut, op, src1, src2, dest,
shadow_on, shadow_off)
if is_branch:
branch_ok, branch_fail = dest
dest = src2
- print ("sim %d: (%d, %d, %d, %d, (%d, %d))" % \
- (i, src1, src2, dest, op, shadow_on, shadow_off))
+ print("sim %d: (%d, %d, %d, %d, (%d, %d))" %
+ (i, src1, src2, dest, op, shadow_on, shadow_off))
branch_res = alusim.op(op, src1, src2, dest)
if is_branch:
if branch_res:
if False:
instrs = create_random_ops(dut, 15, True, 4)
- if True: # LD/ST test (with immediate)
- instrs.append( (1, 2, 0, 0x20, 1, 1, (0, 0)) ) # LD
+ if True: # LD/ST test (with immediate)
+ instrs.append((1, 2, 0, 0x20, 1, 1, (0, 0))) # LD
#instrs.append( (1, 2, 0, 0x10, 1, 1, (0, 0)) )
if True:
- instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
+ instrs.append((1, 2, 2, 1, 1, 20, (0, 0)))
if True:
- instrs.append( (7, 3, 2, 4, 0, 0, (0, 0)) )
- instrs.append( (7, 6, 6, 2, 0, 0, (0, 0)) )
- instrs.append( (1, 7, 2, 2, 0, 0, (0, 0)) )
+ instrs.append((7, 3, 2, 4, 0, 0, (0, 0)))
+ instrs.append((7, 6, 6, 2, 0, 0, (0, 0)))
+ instrs.append((1, 7, 2, 2, 0, 0, (0, 0)))
if True:
instrs.append((2, 3, 3, 0, 0, 0, (0, 0)))
instrs.append((3, 5, 5, 0, 0, 0, (0, 0)))
if False:
- instrs.append( (3, 3, 4, 0, 0, 13979, (0, 0)))
- instrs.append( (6, 4, 1, 2, 0, 40976, (0, 0)))
- instrs.append( (1, 4, 7, 4, 1, 23652, (0, 0)))
+ instrs.append((3, 3, 4, 0, 0, 13979, (0, 0)))
+ instrs.append((6, 4, 1, 2, 0, 40976, (0, 0)))
+ instrs.append((1, 4, 7, 4, 1, 23652, (0, 0)))
if False:
instrs.append((5, 6, 2, 1))
if False:
# Write-after-Write Hazard
- instrs.append( (3, 6, 7, 2) )
- instrs.append( (4, 4, 7, 1) )
+ instrs.append((3, 6, 7, 2))
+ instrs.append((4, 4, 7, 1))
if False:
# self-read/write-after-write followed by Read-after-Write
if False:
# very weird failure
- instrs.append( (5, 2, 5, 2) )
- instrs.append( (2, 6, 3, 0) )
- instrs.append( (4, 2, 2, 1) )
+ instrs.append((5, 2, 5, 2))
+ instrs.append((2, 6, 3, 0))
+ instrs.append((4, 2, 2, 1))
if False:
v1 = 4
instrs.append((4, 2, 1, 2, (1, 0)))
if False:
- instrs.append( (4, 3, 5, 1, 0, (0, 0)) )
- instrs.append( (5, 2, 3, 1, 0, (0, 0)) )
- instrs.append( (7, 1, 5, 2, 0, (0, 0)) )
- instrs.append( (5, 6, 6, 4, 0, (0, 0)) )
- instrs.append( (7, 5, 2, 2, 0, (1, 0)) )
- instrs.append( (1, 7, 5, 0, 0, (0, 1)) )
- instrs.append( (1, 6, 1, 2, 0, (1, 0)) )
- instrs.append( (1, 6, 7, 3, 0, (0, 0)) )
- instrs.append( (6, 7, 7, 0, 0, (0, 0)) )
+ instrs.append((4, 3, 5, 1, 0, (0, 0)))
+ instrs.append((5, 2, 3, 1, 0, (0, 0)))
+ instrs.append((7, 1, 5, 2, 0, (0, 0)))
+ instrs.append((5, 6, 6, 4, 0, (0, 0)))
+ instrs.append((7, 5, 2, 2, 0, (1, 0)))
+ instrs.append((1, 7, 5, 0, 0, (0, 1)))
+ instrs.append((1, 6, 1, 2, 0, (1, 0)))
+ instrs.append((1, 6, 7, 3, 0, (0, 0)))
+ instrs.append((6, 7, 7, 0, 0, (0, 0)))
# issue instruction(s), wait for issue to be free before proceeding
for i, instr in enumerate(instrs):
src1, src2, dest, op, opi, imm, (br_ok, br_fail) = instr
- print ("instr %d: (%d, %d, %d, %d, %d, %d)" % \
- (i, src1, src2, dest, op, opi, imm))
+ print("instr %d: (%d, %d, %d, %d, %d, %d)" %
+ (i, src1, src2, dest, op, opi, imm))
alusim.op(op, opi, imm, src1, src2, dest)
yield from instr_q(dut, op, opi, imm, src1, src2, dest,
br_ok, br_fail)
f.write(vl)
run_simulation(dut, scoreboard_sim(dut, alusim),
- vcd_name='test_scoreboard6600.vcd')
+ vcd_name='test_scoreboard6600.vcd')
- #run_simulation(dut, scoreboard_branch_sim(dut, alusim),
+ # run_simulation(dut, scoreboard_branch_sim(dut, alusim),
# vcd_name='test_scoreboard6600.vcd')
self.d1_o = Signal(DATA_WIDTH) # output
DEPTH = int(math.pow(2, ADDR_WIDTH))
- self.ram = Memory(DATA_WIDTH, DEPTH)
+ self.ram = Memory(width=DATA_WIDTH, depth=DEPTH)
#
# localparam DEPTH = 2**ADDR_WIDTH;
#
self.d1_o = Signal(DATA_WIDTH) # output
DEPTH = int(math.pow(2, ADDR_WIDTH))
- self.ram = Memory(DATA_WIDTH, DEPTH)
+ self.ram = Memory(width=DATA_WIDTH, depth=DEPTH)
#
# localparam DEPTH = 2**ADDR_WIDTH;
class Minerva(Elaboratable):
def __init__(self, reset_address=0x00000000,
- with_icache=False,
- icache_nways=1, icache_nlines=256, icache_nwords=8, icache_base=0, icache_limit=2**31,
- with_dcache=False,
- dcache_nways=1, dcache_nlines=256, dcache_nwords=8, dcache_base=0, dcache_limit=2**31,
- with_muldiv=False,
- with_debug=False,
- with_trigger=False, nb_triggers=8,
- with_rvfi=False):
+ with_icache=False,
+ icache_nways=1, icache_nlines=256, icache_nwords=8, icache_base=0, icache_limit=2**31,
+ with_dcache=False,
+ dcache_nways=1, dcache_nlines=256, dcache_nwords=8, dcache_base=0, dcache_limit=2**31,
+ with_muldiv=False,
+ with_debug=False,
+ with_trigger=False, nb_triggers=8,
+ with_rvfi=False):
self.external_interrupt = Signal(32)
self.timer_interrupt = Signal()
self.software_interrupt = Signal()
self.rvfi = Record(rvfi_layout)
self.reset_address = reset_address
- self.with_icache = with_icache
- self.icache_args = icache_nways, icache_nlines, icache_nwords, icache_base, icache_limit
- self.with_dcache = with_dcache
- self.dcache_args = dcache_nways, dcache_nlines, dcache_nwords, dcache_base, dcache_limit
- self.with_muldiv = with_muldiv
- self.with_debug = with_debug
- self.with_trigger = with_trigger
- self.nb_triggers = nb_triggers
- self.with_rvfi = with_rvfi
+ self.with_icache = with_icache
+ self.icache_args = icache_nways, icache_nlines, icache_nwords, icache_base, icache_limit
+ self.with_dcache = with_dcache
+ self.dcache_args = dcache_nways, dcache_nlines, dcache_nwords, dcache_base, dcache_limit
+ self.with_muldiv = with_muldiv
+ self.with_debug = with_debug
+ self.with_trigger = with_trigger
+ self.nb_triggers = nb_triggers
+ self.with_rvfi = with_rvfi
def elaborate(self, platform):
cpu = Module()
# units
- pc_sel = cpu.submodules.pc_sel = PCSelector()
- data_sel = cpu.submodules.data_sel = DataSelector()
- adder = cpu.submodules.adder = Adder()
- compare = cpu.submodules.compare = CompareUnit()
- decoder = cpu.submodules.decoder = InstructionDecoder(self.with_muldiv)
+ pc_sel = cpu.submodules.pc_sel = PCSelector()
+ data_sel = cpu.submodules.data_sel = DataSelector()
+ adder = cpu.submodules.adder = Adder()
+ compare = cpu.submodules.compare = CompareUnit()
+ decoder = cpu.submodules.decoder = InstructionDecoder(self.with_muldiv)
exception = cpu.submodules.exception = ExceptionUnit()
- logic = cpu.submodules.logic = LogicUnit()
- predict = cpu.submodules.predict = BranchPredictor()
- shifter = cpu.submodules.shifter = Shifter()
+ logic = cpu.submodules.logic = LogicUnit()
+ predict = cpu.submodules.predict = BranchPredictor()
+ shifter = cpu.submodules.shifter = Shifter()
if self.with_icache:
fetch = cpu.submodules.fetch = CachedFetchUnit(*self.icache_args)
fetch = cpu.submodules.fetch = BareFetchUnit()
if self.with_dcache:
- loadstore = cpu.submodules.loadstore = CachedLoadStoreUnit(*self.dcache_args)
+ loadstore = cpu.submodules.loadstore = CachedLoadStoreUnit(
+ *self.dcache_args)
else:
loadstore = cpu.submodules.loadstore = BareLoadStoreUnit()
if self.with_muldiv:
multiplier = Multiplier() if not self.with_rvfi else DummyMultiplier()
- divider = Divider() if not self.with_rvfi else DummyDivider()
+ divider = Divider() if not self.with_rvfi else DummyDivider()
cpu.submodules.multiplier = multiplier
- cpu.submodules.divider = divider
+ cpu.submodules.divider = divider
if self.with_debug:
debug = cpu.submodules.debug = DebugUnit()
gprf = Memory(width=32, depth=32)
gprf_rp1 = gprf.read_port()
gprf_rp2 = gprf.read_port()
- gprf_wp = gprf.write_port()
+ gprf_wp = gprf.write_port()
cpu.submodules += gprf_rp1, gprf_rp2, gprf_wp
csrf = cpu.submodules.csrf = CSRFile()
cpu.d.comb += [
pc_sel.f_pc.eq(f.sink.pc),
pc_sel.d_pc.eq(d.sink.pc),
- pc_sel.d_branch_predict_taken.eq(predict.d_branch_taken & ~predict.d_fetch_misaligned),
+ pc_sel.d_branch_predict_taken.eq(
+ predict.d_branch_taken & ~predict.d_fetch_misaligned),
pc_sel.d_branch_target.eq(predict.d_branch_target),
pc_sel.d_valid.eq(d.valid),
pc_sel.x_pc.eq(x.sink.pc),
]
cpu.d.comb += [
- adder.sub.eq(x.sink.adder & x.sink.adder_sub | x.sink.compare | x.sink.branch),
+ adder.sub.eq(x.sink.adder & x.sink.adder_sub |
+ x.sink.compare | x.sink.branch),
adder.src1.eq(x.sink.src1),
adder.src2.eq(Mux(x.sink.store, x.sink.immediate, x.sink.src2))
]
cpu.d.comb += [
# compare.op is shared by compare and branch instructions.
- compare.op.eq(Mux(x.sink.compare, x.sink.funct3 << 1, x.sink.funct3)),
+ compare.op.eq(
+ Mux(x.sink.compare, x.sink.funct3 << 1, x.sink.funct3)),
compare.zero.eq(x.sink.src1 == x.sink.src2),
compare.negative.eq(adder.result[-1]),
compare.overflow.eq(adder.overflow),
exception.external_interrupt.eq(self.external_interrupt),
exception.timer_interrupt.eq(self.timer_interrupt),
exception.software_interrupt.eq(self.software_interrupt),
- exception.m_fetch_misaligned.eq(m.sink.branch_taken & m.sink.branch_target[:2].bool()),
+ exception.m_fetch_misaligned.eq(
+ m.sink.branch_taken & m.sink.branch_target[:2].bool()),
exception.m_fetch_error.eq(m.sink.fetch_error),
exception.m_fetch_badaddr.eq(m.sink.fetch_badaddr),
- exception.m_load_misaligned.eq(m.sink.load & m.sink.loadstore_misaligned),
+ exception.m_load_misaligned.eq(
+ m.sink.load & m.sink.loadstore_misaligned),
exception.m_load_error.eq(loadstore.m_load_error),
- exception.m_store_misaligned.eq(m.sink.store & m.sink.loadstore_misaligned),
+ exception.m_store_misaligned.eq(
+ m.sink.store & m.sink.loadstore_misaligned),
exception.m_store_error.eq(loadstore.m_store_error),
exception.m_loadstore_badaddr.eq(loadstore.m_badaddr),
exception.m_branch_target.eq(m.sink.branch_target),
m_lock = Signal()
cpu.d.comb += [
- x_raw_rs1.eq((x.sink.rd != 0) & (x.sink.rd == decoder.rs1) & x.sink.rd_we),
- m_raw_rs1.eq((m.sink.rd != 0) & (m.sink.rd == decoder.rs1) & m.sink.rd_we),
- w_raw_rs1.eq((w.sink.rd != 0) & (w.sink.rd == decoder.rs1) & w.sink.rd_we),
-
- x_raw_rs2.eq((x.sink.rd != 0) & (x.sink.rd == decoder.rs2) & x.sink.rd_we),
- m_raw_rs2.eq((m.sink.rd != 0) & (m.sink.rd == decoder.rs2) & m.sink.rd_we),
- w_raw_rs2.eq((w.sink.rd != 0) & (w.sink.rd == decoder.rs2) & w.sink.rd_we),
-
- x_raw_csr.eq((x.sink.csr_adr == decoder.immediate) & x.sink.csr_we),
- m_raw_csr.eq((m.sink.csr_adr == decoder.immediate) & m.sink.csr_we),
-
- x_lock.eq(~x.sink.bypass_x & (decoder.rs1_re & x_raw_rs1 | decoder.rs2_re & x_raw_rs2) | decoder.csr & x_raw_csr),
- m_lock.eq(~m.sink.bypass_m & (decoder.rs1_re & m_raw_rs1 | decoder.rs2_re & m_raw_rs2) | decoder.csr & m_raw_csr)
+ x_raw_rs1.eq((x.sink.rd != 0) & (
+ x.sink.rd == decoder.rs1) & x.sink.rd_we),
+ m_raw_rs1.eq((m.sink.rd != 0) & (
+ m.sink.rd == decoder.rs1) & m.sink.rd_we),
+ w_raw_rs1.eq((w.sink.rd != 0) & (
+ w.sink.rd == decoder.rs1) & w.sink.rd_we),
+
+ x_raw_rs2.eq((x.sink.rd != 0) & (
+ x.sink.rd == decoder.rs2) & x.sink.rd_we),
+ m_raw_rs2.eq((m.sink.rd != 0) & (
+ m.sink.rd == decoder.rs2) & m.sink.rd_we),
+ w_raw_rs2.eq((w.sink.rd != 0) & (
+ w.sink.rd == decoder.rs2) & w.sink.rd_we),
+
+ x_raw_csr.eq((x.sink.csr_adr == decoder.immediate)
+ & x.sink.csr_we),
+ m_raw_csr.eq((m.sink.csr_adr == decoder.immediate)
+ & m.sink.csr_we),
+
+ x_lock.eq(~x.sink.bypass_x & (decoder.rs1_re & x_raw_rs1 |
+ decoder.rs2_re & x_raw_rs2) | decoder.csr & x_raw_csr),
+ m_lock.eq(~m.sink.bypass_m & (decoder.rs1_re & m_raw_rs1 |
+ decoder.rs2_re & m_raw_rs2) | decoder.csr & m_raw_csr)
]
if self.with_debug:
- d.stall_on((x_lock & x.valid | m_lock & m.valid) & d.valid & ~debug.dcsr_step)
+ d.stall_on((x_lock & x.valid | m_lock & m.valid)
+ & d.valid & ~debug.dcsr_step)
else:
d.stall_on((x_lock & x.valid | m_lock & m.valid) & d.valid)
cpu.d.comb += x_csr_result.eq(x_csr_src1)
cpu.d.comb += [
- csrf_wp.en.eq(m.sink.csr & m.sink.csr_we & m.valid & ~exception.m_raise & ~m.stall),
+ csrf_wp.en.eq(m.sink.csr & m.sink.csr_we & m.valid &
+ ~exception.m_raise & ~m.stall),
csrf_wp.addr.eq(m.sink.csr_adr),
csrf_wp.data.eq(m.sink.csr_result)
]
]
with cpu.Else():
cpu.d.comb += [
- gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we & w.valid & ~w.sink.exception),
+ gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we &
+ w.valid & ~w.sink.exception),
gprf_wp.addr.eq(w.sink.rd),
gprf_wp.data.eq(w_result)
]
predict.d_rs1_re.eq(decoder.rs1_re)
]
- a.kill_on(predict.d_branch_taken & ~predict.d_fetch_misaligned & d.valid)
+ a.kill_on(predict.d_branch_taken & ~
+ predict.d_fetch_misaligned & d.valid)
for s in a, f:
- s.kill_on(m.sink.branch_predict_taken & ~m.sink.branch_taken & m.valid)
+ s.kill_on(m.sink.branch_predict_taken & ~
+ m.sink.branch_taken & m.valid)
for s in a, f, d:
- s.kill_on(~m.sink.branch_predict_taken & m.sink.branch_taken & m.valid)
+ s.kill_on(~m.sink.branch_predict_taken &
+ m.sink.branch_taken & m.valid)
s.kill_on((exception.m_raise | m.sink.mret) & m.valid)
# debug unit
rvficon.d_rs2_rdata.eq(Mux(decoder.rs2_re, d_src2, 0)),
rvficon.d_stall.eq(d.stall),
rvficon.x_mem_addr.eq(loadstore.x_addr[2:] << 2),
- rvficon.x_mem_wmask.eq(Mux(loadstore.x_store, loadstore.x_mask, 0)),
- rvficon.x_mem_rmask.eq(Mux(loadstore.x_load, loadstore.x_mask, 0)),
+ rvficon.x_mem_wmask.eq(
+ Mux(loadstore.x_store, loadstore.x_mask, 0)),
+ rvficon.x_mem_rmask.eq(
+ Mux(loadstore.x_load, loadstore.x_mask, 0)),
rvficon.x_mem_wdata.eq(loadstore.x_store_data),
rvficon.x_stall.eq(x.stall),
rvficon.m_mem_rdata.eq(loadstore.m_load_data),
d.source.mret.eq(decoder.mret),
d.source.src1.eq(d_src1),
d.source.src2.eq(d_src2),
- d.source.branch_predict_taken.eq(predict.d_branch_taken & ~predict.d_fetch_misaligned),
+ d.source.branch_predict_taken.eq(
+ predict.d_branch_taken & ~predict.d_fetch_misaligned),
d.source.branch_target.eq(predict.d_branch_target)
]
if self.with_muldiv:
x.source.shift.eq(x.sink.shift),
x.source.mret.eq(x.sink.mret),
x.source.condition_met.eq(compare.condition_met),
- x.source.branch_taken.eq(x.sink.jump | x.sink.branch & compare.condition_met),
- x.source.branch_target.eq(Mux(x.sink.jump & x.sink.rs1_re, adder.result[1:] << 1, x.sink.branch_target)),
+ x.source.branch_taken.eq(
+ x.sink.jump | x.sink.branch & compare.condition_met),
+ x.source.branch_target.eq(
+ Mux(x.sink.jump & x.sink.rs1_re, adder.result[1:] << 1, x.sink.branch_target)),
x.source.branch_predict_taken.eq(x.sink.branch_predict_taken),
x.source.csr.eq(x.sink.csr),
x.source.csr_adr.eq(x.sink.csr_adr),
--- /dev/null
+/spec_cache_check
\ No newline at end of file
from ..isa import Funct3
-def test_op(funct3, src1, src2, result):
+def tst_op(funct3, src1, src2, result):
def test(self):
with Simulator(self.dut) as sim:
def process():
# DIV ------------------------------------------------------------------------
- test_div_0 = test_op(Funct3.DIV, 0x00000000, 0x00000000, result=0xffffffff)
- test_div_1 = test_op(Funct3.DIV, 0x00000000, 0x00000001, result=0x00000000)
- test_div_2 = test_op(Funct3.DIV, 0x00000000, 0xffffffff, result=0x00000000)
- test_div_3 = test_op(Funct3.DIV, 0x00000000, 0x7fffffff, result=0x00000000)
- test_div_4 = test_op(Funct3.DIV, 0x00000000, 0x80000000, result=0x00000000)
-
- test_div_5 = test_op(Funct3.DIV, 0x00000001, 0x00000000, result=0xffffffff)
- test_div_6 = test_op(Funct3.DIV, 0x00000001, 0x00000001, result=0x00000001)
- test_div_7 = test_op(Funct3.DIV, 0x00000001, 0xffffffff, result=0xffffffff)
- test_div_8 = test_op(Funct3.DIV, 0x00000001, 0x7fffffff, result=0x00000000)
- test_div_9 = test_op(Funct3.DIV, 0x00000001, 0x80000000, result=0x00000000)
-
- test_div_10 = test_op(Funct3.DIV, 0xffffffff, 0x00000000, result=0xffffffff)
- test_div_11 = test_op(Funct3.DIV, 0xffffffff, 0x00000001, result=0xffffffff)
- test_div_12 = test_op(Funct3.DIV, 0xffffffff, 0xffffffff, result=0x00000001)
- test_div_13 = test_op(Funct3.DIV, 0xffffffff, 0x7fffffff, result=0x00000000)
- test_div_14 = test_op(Funct3.DIV, 0xffffffff, 0x80000000, result=0x00000000)
-
- test_div_15 = test_op(Funct3.DIV, 0x7fffffff, 0x00000000, result=0xffffffff)
- test_div_16 = test_op(Funct3.DIV, 0x7fffffff, 0x00000001, result=0x7fffffff)
- test_div_17 = test_op(Funct3.DIV, 0x7fffffff, 0xffffffff, result=0x80000001)
- test_div_18 = test_op(Funct3.DIV, 0x7fffffff, 0x7fffffff, result=0x00000001)
- test_div_19 = test_op(Funct3.DIV, 0x7fffffff, 0x80000000, result=0x00000000)
-
- test_div_20 = test_op(Funct3.DIV, 0x80000000, 0x00000000, result=0xffffffff)
- test_div_21 = test_op(Funct3.DIV, 0x80000000, 0x00000001, result=0x80000000)
- test_div_22 = test_op(Funct3.DIV, 0x80000000, 0xffffffff, result=0x80000000)
- test_div_23 = test_op(Funct3.DIV, 0x80000000, 0x7fffffff, result=0xffffffff)
- test_div_24 = test_op(Funct3.DIV, 0x80000000, 0x80000000, result=0x00000001)
+ test_div_0 = tst_op(Funct3.DIV, 0x00000000, 0x00000000, result=0xffffffff)
+ test_div_1 = tst_op(Funct3.DIV, 0x00000000, 0x00000001, result=0x00000000)
+ test_div_2 = tst_op(Funct3.DIV, 0x00000000, 0xffffffff, result=0x00000000)
+ test_div_3 = tst_op(Funct3.DIV, 0x00000000, 0x7fffffff, result=0x00000000)
+ test_div_4 = tst_op(Funct3.DIV, 0x00000000, 0x80000000, result=0x00000000)
+
+ test_div_5 = tst_op(Funct3.DIV, 0x00000001, 0x00000000, result=0xffffffff)
+ test_div_6 = tst_op(Funct3.DIV, 0x00000001, 0x00000001, result=0x00000001)
+ test_div_7 = tst_op(Funct3.DIV, 0x00000001, 0xffffffff, result=0xffffffff)
+ test_div_8 = tst_op(Funct3.DIV, 0x00000001, 0x7fffffff, result=0x00000000)
+ test_div_9 = tst_op(Funct3.DIV, 0x00000001, 0x80000000, result=0x00000000)
+
+ test_div_10 = tst_op(Funct3.DIV, 0xffffffff,
+ 0x00000000, result=0xffffffff)
+ test_div_11 = tst_op(Funct3.DIV, 0xffffffff,
+ 0x00000001, result=0xffffffff)
+ test_div_12 = tst_op(Funct3.DIV, 0xffffffff,
+ 0xffffffff, result=0x00000001)
+ test_div_13 = tst_op(Funct3.DIV, 0xffffffff,
+ 0x7fffffff, result=0x00000000)
+ test_div_14 = tst_op(Funct3.DIV, 0xffffffff,
+ 0x80000000, result=0x00000000)
+
+ test_div_15 = tst_op(Funct3.DIV, 0x7fffffff,
+ 0x00000000, result=0xffffffff)
+ test_div_16 = tst_op(Funct3.DIV, 0x7fffffff,
+ 0x00000001, result=0x7fffffff)
+ test_div_17 = tst_op(Funct3.DIV, 0x7fffffff,
+ 0xffffffff, result=0x80000001)
+ test_div_18 = tst_op(Funct3.DIV, 0x7fffffff,
+ 0x7fffffff, result=0x00000001)
+ test_div_19 = tst_op(Funct3.DIV, 0x7fffffff,
+ 0x80000000, result=0x00000000)
+
+ test_div_20 = tst_op(Funct3.DIV, 0x80000000,
+ 0x00000000, result=0xffffffff)
+ test_div_21 = tst_op(Funct3.DIV, 0x80000000,
+ 0x00000001, result=0x80000000)
+ test_div_22 = tst_op(Funct3.DIV, 0x80000000,
+ 0xffffffff, result=0x80000000)
+ test_div_23 = tst_op(Funct3.DIV, 0x80000000,
+ 0x7fffffff, result=0xffffffff)
+ test_div_24 = tst_op(Funct3.DIV, 0x80000000,
+ 0x80000000, result=0x00000001)
# DIVU -----------------------------------------------------------------------
- test_divu_0 = test_op(Funct3.DIVU, 0x00000000, 0x00000000, result=0xffffffff)
- test_divu_1 = test_op(Funct3.DIVU, 0x00000000, 0x00000001, result=0x00000000)
- test_divu_2 = test_op(Funct3.DIVU, 0x00000000, 0xffffffff, result=0x00000000)
- test_divu_3 = test_op(Funct3.DIVU, 0x00000000, 0x7fffffff, result=0x00000000)
- test_divu_4 = test_op(Funct3.DIVU, 0x00000000, 0x80000000, result=0x00000000)
-
- test_divu_5 = test_op(Funct3.DIVU, 0x00000001, 0x00000000, result=0xffffffff)
- test_divu_6 = test_op(Funct3.DIVU, 0x00000001, 0x00000001, result=0x00000001)
- test_divu_7 = test_op(Funct3.DIVU, 0x00000001, 0xffffffff, result=0x00000000)
- test_divu_8 = test_op(Funct3.DIVU, 0x00000001, 0x7fffffff, result=0x00000000)
- test_divu_9 = test_op(Funct3.DIVU, 0x00000001, 0x80000000, result=0x00000000)
-
- test_divu_10 = test_op(Funct3.DIVU, 0xffffffff, 0x00000000, result=0xffffffff)
- test_divu_11 = test_op(Funct3.DIVU, 0xffffffff, 0x00000001, result=0xffffffff)
- test_divu_12 = test_op(Funct3.DIVU, 0xffffffff, 0xffffffff, result=0x00000001)
- test_divu_13 = test_op(Funct3.DIVU, 0xffffffff, 0x7fffffff, result=0x00000002)
- test_divu_14 = test_op(Funct3.DIVU, 0xffffffff, 0x80000000, result=0x00000001)
-
- test_divu_15 = test_op(Funct3.DIVU, 0x7fffffff, 0x00000000, result=0xffffffff)
- test_divu_16 = test_op(Funct3.DIVU, 0x7fffffff, 0x00000001, result=0x7fffffff)
- test_divu_17 = test_op(Funct3.DIVU, 0x7fffffff, 0xffffffff, result=0x00000000)
- test_divu_18 = test_op(Funct3.DIVU, 0x7fffffff, 0x7fffffff, result=0x00000001)
- test_divu_19 = test_op(Funct3.DIVU, 0x7fffffff, 0x80000000, result=0x00000000)
-
- test_divu_20 = test_op(Funct3.DIVU, 0x80000000, 0x00000000, result=0xffffffff)
- test_divu_21 = test_op(Funct3.DIVU, 0x80000000, 0x00000001, result=0x80000000)
- test_divu_22 = test_op(Funct3.DIVU, 0x80000000, 0xffffffff, result=0x00000000)
- test_divu_23 = test_op(Funct3.DIVU, 0x80000000, 0x7fffffff, result=0x00000001)
- test_divu_24 = test_op(Funct3.DIVU, 0x80000000, 0x80000000, result=0x00000001)
+ test_divu_0 = tst_op(Funct3.DIVU, 0x00000000,
+ 0x00000000, result=0xffffffff)
+ test_divu_1 = tst_op(Funct3.DIVU, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_divu_2 = tst_op(Funct3.DIVU, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_divu_3 = tst_op(Funct3.DIVU, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_divu_4 = tst_op(Funct3.DIVU, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_divu_5 = tst_op(Funct3.DIVU, 0x00000001,
+ 0x00000000, result=0xffffffff)
+ test_divu_6 = tst_op(Funct3.DIVU, 0x00000001,
+ 0x00000001, result=0x00000001)
+ test_divu_7 = tst_op(Funct3.DIVU, 0x00000001,
+ 0xffffffff, result=0x00000000)
+ test_divu_8 = tst_op(Funct3.DIVU, 0x00000001,
+ 0x7fffffff, result=0x00000000)
+ test_divu_9 = tst_op(Funct3.DIVU, 0x00000001,
+ 0x80000000, result=0x00000000)
+
+ test_divu_10 = tst_op(Funct3.DIVU, 0xffffffff,
+ 0x00000000, result=0xffffffff)
+ test_divu_11 = tst_op(Funct3.DIVU, 0xffffffff,
+ 0x00000001, result=0xffffffff)
+ test_divu_12 = tst_op(Funct3.DIVU, 0xffffffff,
+ 0xffffffff, result=0x00000001)
+ test_divu_13 = tst_op(Funct3.DIVU, 0xffffffff,
+ 0x7fffffff, result=0x00000002)
+ test_divu_14 = tst_op(Funct3.DIVU, 0xffffffff,
+ 0x80000000, result=0x00000001)
+
+ test_divu_15 = tst_op(Funct3.DIVU, 0x7fffffff,
+ 0x00000000, result=0xffffffff)
+ test_divu_16 = tst_op(Funct3.DIVU, 0x7fffffff,
+ 0x00000001, result=0x7fffffff)
+ test_divu_17 = tst_op(Funct3.DIVU, 0x7fffffff,
+ 0xffffffff, result=0x00000000)
+ test_divu_18 = tst_op(Funct3.DIVU, 0x7fffffff,
+ 0x7fffffff, result=0x00000001)
+ test_divu_19 = tst_op(Funct3.DIVU, 0x7fffffff,
+ 0x80000000, result=0x00000000)
+
+ test_divu_20 = tst_op(Funct3.DIVU, 0x80000000,
+ 0x00000000, result=0xffffffff)
+ test_divu_21 = tst_op(Funct3.DIVU, 0x80000000,
+ 0x00000001, result=0x80000000)
+ test_divu_22 = tst_op(Funct3.DIVU, 0x80000000,
+ 0xffffffff, result=0x00000000)
+ test_divu_23 = tst_op(Funct3.DIVU, 0x80000000,
+ 0x7fffffff, result=0x00000001)
+ test_divu_24 = tst_op(Funct3.DIVU, 0x80000000,
+ 0x80000000, result=0x00000001)
# REM ------------------------------------------------------------------------
- test_rem_0 = test_op(Funct3.REM, 0x00000000, 0x00000000, result=0x00000000)
- test_rem_1 = test_op(Funct3.REM, 0x00000000, 0x00000001, result=0x00000000)
- test_rem_2 = test_op(Funct3.REM, 0x00000000, 0xffffffff, result=0x00000000)
- test_rem_3 = test_op(Funct3.REM, 0x00000000, 0x7fffffff, result=0x00000000)
- test_rem_4 = test_op(Funct3.REM, 0x00000000, 0x80000000, result=0x00000000)
-
- test_rem_5 = test_op(Funct3.REM, 0x00000001, 0x00000000, result=0x00000001)
- test_rem_6 = test_op(Funct3.REM, 0x00000001, 0x00000001, result=0x00000000)
- test_rem_7 = test_op(Funct3.REM, 0x00000001, 0xffffffff, result=0x00000000)
- test_rem_8 = test_op(Funct3.REM, 0x00000001, 0x7fffffff, result=0x00000001)
- test_rem_9 = test_op(Funct3.REM, 0x00000001, 0x80000000, result=0x00000001)
-
- test_rem_10 = test_op(Funct3.REM, 0xffffffff, 0x00000000, result=0xffffffff)
- test_rem_11 = test_op(Funct3.REM, 0xffffffff, 0x00000001, result=0x00000000)
- test_rem_12 = test_op(Funct3.REM, 0xffffffff, 0xffffffff, result=0x00000000)
- test_rem_13 = test_op(Funct3.REM, 0xffffffff, 0x7fffffff, result=0xffffffff)
- test_rem_14 = test_op(Funct3.REM, 0xffffffff, 0x80000000, result=0xffffffff)
-
- test_rem_15 = test_op(Funct3.REM, 0x7fffffff, 0x00000000, result=0x7fffffff)
- test_rem_16 = test_op(Funct3.REM, 0x7fffffff, 0x00000001, result=0x00000000)
- test_rem_17 = test_op(Funct3.REM, 0x7fffffff, 0xffffffff, result=0x00000000)
- test_rem_18 = test_op(Funct3.REM, 0x7fffffff, 0x7fffffff, result=0x00000000)
- test_rem_19 = test_op(Funct3.REM, 0x7fffffff, 0x80000000, result=0x7fffffff)
-
- test_rem_20 = test_op(Funct3.REM, 0x80000000, 0x00000000, result=0x80000000)
- test_rem_21 = test_op(Funct3.REM, 0x80000000, 0x00000001, result=0x00000000)
- test_rem_22 = test_op(Funct3.REM, 0x80000000, 0xffffffff, result=0x00000000)
- test_rem_23 = test_op(Funct3.REM, 0x80000000, 0x7fffffff, result=0xffffffff)
- test_rem_24 = test_op(Funct3.REM, 0x80000000, 0x80000000, result=0x00000000)
+ test_rem_0 = tst_op(Funct3.REM, 0x00000000, 0x00000000, result=0x00000000)
+ test_rem_1 = tst_op(Funct3.REM, 0x00000000, 0x00000001, result=0x00000000)
+ test_rem_2 = tst_op(Funct3.REM, 0x00000000, 0xffffffff, result=0x00000000)
+ test_rem_3 = tst_op(Funct3.REM, 0x00000000, 0x7fffffff, result=0x00000000)
+ test_rem_4 = tst_op(Funct3.REM, 0x00000000, 0x80000000, result=0x00000000)
+
+ test_rem_5 = tst_op(Funct3.REM, 0x00000001, 0x00000000, result=0x00000001)
+ test_rem_6 = tst_op(Funct3.REM, 0x00000001, 0x00000001, result=0x00000000)
+ test_rem_7 = tst_op(Funct3.REM, 0x00000001, 0xffffffff, result=0x00000000)
+ test_rem_8 = tst_op(Funct3.REM, 0x00000001, 0x7fffffff, result=0x00000001)
+ test_rem_9 = tst_op(Funct3.REM, 0x00000001, 0x80000000, result=0x00000001)
+
+ test_rem_10 = tst_op(Funct3.REM, 0xffffffff,
+ 0x00000000, result=0xffffffff)
+ test_rem_11 = tst_op(Funct3.REM, 0xffffffff,
+ 0x00000001, result=0x00000000)
+ test_rem_12 = tst_op(Funct3.REM, 0xffffffff,
+ 0xffffffff, result=0x00000000)
+ test_rem_13 = tst_op(Funct3.REM, 0xffffffff,
+ 0x7fffffff, result=0xffffffff)
+ test_rem_14 = tst_op(Funct3.REM, 0xffffffff,
+ 0x80000000, result=0xffffffff)
+
+ test_rem_15 = tst_op(Funct3.REM, 0x7fffffff,
+ 0x00000000, result=0x7fffffff)
+ test_rem_16 = tst_op(Funct3.REM, 0x7fffffff,
+ 0x00000001, result=0x00000000)
+ test_rem_17 = tst_op(Funct3.REM, 0x7fffffff,
+ 0xffffffff, result=0x00000000)
+ test_rem_18 = tst_op(Funct3.REM, 0x7fffffff,
+ 0x7fffffff, result=0x00000000)
+ test_rem_19 = tst_op(Funct3.REM, 0x7fffffff,
+ 0x80000000, result=0x7fffffff)
+
+ test_rem_20 = tst_op(Funct3.REM, 0x80000000,
+ 0x00000000, result=0x80000000)
+ test_rem_21 = tst_op(Funct3.REM, 0x80000000,
+ 0x00000001, result=0x00000000)
+ test_rem_22 = tst_op(Funct3.REM, 0x80000000,
+ 0xffffffff, result=0x00000000)
+ test_rem_23 = tst_op(Funct3.REM, 0x80000000,
+ 0x7fffffff, result=0xffffffff)
+ test_rem_24 = tst_op(Funct3.REM, 0x80000000,
+ 0x80000000, result=0x00000000)
# REMU -----------------------------------------------------------------------
- test_remu_0 = test_op(Funct3.REMU, 0x00000000, 0x00000000, result=0x00000000)
- test_remu_1 = test_op(Funct3.REMU, 0x00000000, 0x00000001, result=0x00000000)
- test_remu_2 = test_op(Funct3.REMU, 0x00000000, 0xffffffff, result=0x00000000)
- test_remu_3 = test_op(Funct3.REMU, 0x00000000, 0x7fffffff, result=0x00000000)
- test_remu_4 = test_op(Funct3.REMU, 0x00000000, 0x80000000, result=0x00000000)
-
- test_remu_5 = test_op(Funct3.REMU, 0x00000001, 0x00000000, result=0x00000001)
- test_remu_6 = test_op(Funct3.REMU, 0x00000001, 0x00000001, result=0x00000000)
- test_remu_7 = test_op(Funct3.REMU, 0x00000001, 0xffffffff, result=0x00000001)
- test_remu_8 = test_op(Funct3.REMU, 0x00000001, 0x7fffffff, result=0x00000001)
- test_remu_9 = test_op(Funct3.REMU, 0x00000001, 0x80000000, result=0x00000001)
-
- test_remu_10 = test_op(Funct3.REMU, 0xffffffff, 0x00000000, result=0xffffffff)
- test_remu_11 = test_op(Funct3.REMU, 0xffffffff, 0x00000001, result=0x00000000)
- test_remu_12 = test_op(Funct3.REMU, 0xffffffff, 0xffffffff, result=0x00000000)
- test_remu_13 = test_op(Funct3.REMU, 0xffffffff, 0x7fffffff, result=0x00000001)
- test_remu_14 = test_op(Funct3.REMU, 0xffffffff, 0x80000000, result=0x7fffffff)
-
- test_remu_15 = test_op(Funct3.REMU, 0x7fffffff, 0x00000000, result=0x7fffffff)
- test_remu_16 = test_op(Funct3.REMU, 0x7fffffff, 0x00000001, result=0x00000000)
- test_remu_17 = test_op(Funct3.REMU, 0x7fffffff, 0xffffffff, result=0x7fffffff)
- test_remu_18 = test_op(Funct3.REMU, 0x7fffffff, 0x7fffffff, result=0x00000000)
- test_remu_19 = test_op(Funct3.REMU, 0x7fffffff, 0x80000000, result=0x7fffffff)
-
- test_remu_20 = test_op(Funct3.REMU, 0x80000000, 0x00000000, result=0x80000000)
- test_remu_21 = test_op(Funct3.REMU, 0x80000000, 0x00000001, result=0x00000000)
- test_remu_22 = test_op(Funct3.REMU, 0x80000000, 0xffffffff, result=0x80000000)
- test_remu_23 = test_op(Funct3.REMU, 0x80000000, 0x7fffffff, result=0x00000001)
- test_remu_24 = test_op(Funct3.REMU, 0x80000000, 0x80000000, result=0x00000000)
+ test_remu_0 = tst_op(Funct3.REMU, 0x00000000,
+ 0x00000000, result=0x00000000)
+ test_remu_1 = tst_op(Funct3.REMU, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_remu_2 = tst_op(Funct3.REMU, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_remu_3 = tst_op(Funct3.REMU, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_remu_4 = tst_op(Funct3.REMU, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_remu_5 = tst_op(Funct3.REMU, 0x00000001,
+ 0x00000000, result=0x00000001)
+ test_remu_6 = tst_op(Funct3.REMU, 0x00000001,
+ 0x00000001, result=0x00000000)
+ test_remu_7 = tst_op(Funct3.REMU, 0x00000001,
+ 0xffffffff, result=0x00000001)
+ test_remu_8 = tst_op(Funct3.REMU, 0x00000001,
+ 0x7fffffff, result=0x00000001)
+ test_remu_9 = tst_op(Funct3.REMU, 0x00000001,
+ 0x80000000, result=0x00000001)
+
+ test_remu_10 = tst_op(Funct3.REMU, 0xffffffff,
+ 0x00000000, result=0xffffffff)
+ test_remu_11 = tst_op(Funct3.REMU, 0xffffffff,
+ 0x00000001, result=0x00000000)
+ test_remu_12 = tst_op(Funct3.REMU, 0xffffffff,
+ 0xffffffff, result=0x00000000)
+ test_remu_13 = tst_op(Funct3.REMU, 0xffffffff,
+ 0x7fffffff, result=0x00000001)
+ test_remu_14 = tst_op(Funct3.REMU, 0xffffffff,
+ 0x80000000, result=0x7fffffff)
+
+ test_remu_15 = tst_op(Funct3.REMU, 0x7fffffff,
+ 0x00000000, result=0x7fffffff)
+ test_remu_16 = tst_op(Funct3.REMU, 0x7fffffff,
+ 0x00000001, result=0x00000000)
+ test_remu_17 = tst_op(Funct3.REMU, 0x7fffffff,
+ 0xffffffff, result=0x7fffffff)
+ test_remu_18 = tst_op(Funct3.REMU, 0x7fffffff,
+ 0x7fffffff, result=0x00000000)
+ test_remu_19 = tst_op(Funct3.REMU, 0x7fffffff,
+ 0x80000000, result=0x7fffffff)
+
+ test_remu_20 = tst_op(Funct3.REMU, 0x80000000,
+ 0x00000000, result=0x80000000)
+ test_remu_21 = tst_op(Funct3.REMU, 0x80000000,
+ 0x00000001, result=0x00000000)
+ test_remu_22 = tst_op(Funct3.REMU, 0x80000000,
+ 0xffffffff, result=0x80000000)
+ test_remu_23 = tst_op(Funct3.REMU, 0x80000000,
+ 0x7fffffff, result=0x00000001)
+ test_remu_24 = tst_op(Funct3.REMU, 0x80000000,
+ 0x80000000, result=0x00000000)
from ..isa import Funct3
-def test_op(funct3, src1, src2, result):
+def tst_op(funct3, src1, src2, result):
def test(self):
with Simulator(self.dut) as sim:
def process():
# MUL ----------------------------------------------------------------------------
- test_mul_0 = test_op(Funct3.MUL, 0x00000000, 0x00000000, result=0x00000000)
- test_mul_1 = test_op(Funct3.MUL, 0x00000000, 0x00000001, result=0x00000000)
- test_mul_2 = test_op(Funct3.MUL, 0x00000000, 0xffffffff, result=0x00000000)
- test_mul_3 = test_op(Funct3.MUL, 0x00000000, 0x7fffffff, result=0x00000000)
- test_mul_4 = test_op(Funct3.MUL, 0x00000000, 0x80000000, result=0x00000000)
-
- test_mul_5 = test_op(Funct3.MUL, 0x00000001, 0x00000000, result=0x00000000)
- test_mul_6 = test_op(Funct3.MUL, 0x00000001, 0x00000001, result=0x00000001)
- test_mul_7 = test_op(Funct3.MUL, 0x00000001, 0xffffffff, result=0xffffffff)
- test_mul_8 = test_op(Funct3.MUL, 0x00000001, 0x7fffffff, result=0x7fffffff)
- test_mul_9 = test_op(Funct3.MUL, 0x00000001, 0x80000000, result=0x80000000)
-
- test_mul_10 = test_op(Funct3.MUL, 0xffffffff, 0x00000000, result=0x00000000)
- test_mul_11 = test_op(Funct3.MUL, 0xffffffff, 0x00000001, result=0xffffffff)
- test_mul_12 = test_op(Funct3.MUL, 0xffffffff, 0xffffffff, result=0x00000001)
- test_mul_13 = test_op(Funct3.MUL, 0xffffffff, 0x7fffffff, result=0x80000001)
- test_mul_14 = test_op(Funct3.MUL, 0xffffffff, 0x80000000, result=0x80000000)
-
- test_mul_15 = test_op(Funct3.MUL, 0x7fffffff, 0x00000000, result=0x00000000)
- test_mul_16 = test_op(Funct3.MUL, 0x7fffffff, 0x00000001, result=0x7fffffff)
- test_mul_17 = test_op(Funct3.MUL, 0x7fffffff, 0xffffffff, result=0x80000001)
- test_mul_18 = test_op(Funct3.MUL, 0x7fffffff, 0x7fffffff, result=0x00000001)
- test_mul_19 = test_op(Funct3.MUL, 0x7fffffff, 0x80000000, result=0x80000000)
-
- test_mul_20 = test_op(Funct3.MUL, 0x80000000, 0x00000000, result=0x00000000)
- test_mul_21 = test_op(Funct3.MUL, 0x80000000, 0x00000001, result=0x80000000)
- test_mul_22 = test_op(Funct3.MUL, 0x80000000, 0xffffffff, result=0x80000000)
- test_mul_23 = test_op(Funct3.MUL, 0x80000000, 0x7fffffff, result=0x80000000)
- test_mul_24 = test_op(Funct3.MUL, 0x80000000, 0x80000000, result=0x00000000)
+ test_mul_0 = tst_op(Funct3.MUL, 0x00000000,
+ 0x00000000, result=0x00000000)
+ test_mul_1 = tst_op(Funct3.MUL, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_mul_2 = tst_op(Funct3.MUL, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_mul_3 = tst_op(Funct3.MUL, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_mul_4 = tst_op(Funct3.MUL, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_mul_5 = tst_op(Funct3.MUL, 0x00000001,
+ 0x00000000, result=0x00000000)
+ test_mul_6 = tst_op(Funct3.MUL, 0x00000001,
+ 0x00000001, result=0x00000001)
+ test_mul_7 = tst_op(Funct3.MUL, 0x00000001,
+ 0xffffffff, result=0xffffffff)
+ test_mul_8 = tst_op(Funct3.MUL, 0x00000001,
+ 0x7fffffff, result=0x7fffffff)
+ test_mul_9 = tst_op(Funct3.MUL, 0x00000001,
+ 0x80000000, result=0x80000000)
+
+ test_mul_10 = tst_op(Funct3.MUL, 0xffffffff,
+ 0x00000000, result=0x00000000)
+ test_mul_11 = tst_op(Funct3.MUL, 0xffffffff,
+ 0x00000001, result=0xffffffff)
+ test_mul_12 = tst_op(Funct3.MUL, 0xffffffff,
+ 0xffffffff, result=0x00000001)
+ test_mul_13 = tst_op(Funct3.MUL, 0xffffffff,
+ 0x7fffffff, result=0x80000001)
+ test_mul_14 = tst_op(Funct3.MUL, 0xffffffff,
+ 0x80000000, result=0x80000000)
+
+ test_mul_15 = tst_op(Funct3.MUL, 0x7fffffff,
+ 0x00000000, result=0x00000000)
+ test_mul_16 = tst_op(Funct3.MUL, 0x7fffffff,
+ 0x00000001, result=0x7fffffff)
+ test_mul_17 = tst_op(Funct3.MUL, 0x7fffffff,
+ 0xffffffff, result=0x80000001)
+ test_mul_18 = tst_op(Funct3.MUL, 0x7fffffff,
+ 0x7fffffff, result=0x00000001)
+ test_mul_19 = tst_op(Funct3.MUL, 0x7fffffff,
+ 0x80000000, result=0x80000000)
+
+ test_mul_20 = tst_op(Funct3.MUL, 0x80000000,
+ 0x00000000, result=0x00000000)
+ test_mul_21 = tst_op(Funct3.MUL, 0x80000000,
+ 0x00000001, result=0x80000000)
+ test_mul_22 = tst_op(Funct3.MUL, 0x80000000,
+ 0xffffffff, result=0x80000000)
+ test_mul_23 = tst_op(Funct3.MUL, 0x80000000,
+ 0x7fffffff, result=0x80000000)
+ test_mul_24 = tst_op(Funct3.MUL, 0x80000000,
+ 0x80000000, result=0x00000000)
# MULH ---------------------------------------------------------------------------
- test_mulh_0 = test_op(Funct3.MULH, 0x00000000, 0x00000000, result=0x00000000)
- test_mulh_1 = test_op(Funct3.MULH, 0x00000000, 0x00000001, result=0x00000000)
- test_mulh_2 = test_op(Funct3.MULH, 0x00000000, 0xffffffff, result=0x00000000)
- test_mulh_3 = test_op(Funct3.MULH, 0x00000000, 0x7fffffff, result=0x00000000)
- test_mulh_4 = test_op(Funct3.MULH, 0x00000000, 0x80000000, result=0x00000000)
-
- test_mulh_5 = test_op(Funct3.MULH, 0x00000001, 0x00000000, result=0x00000000)
- test_mulh_6 = test_op(Funct3.MULH, 0x00000001, 0x00000001, result=0x00000000)
- test_mulh_7 = test_op(Funct3.MULH, 0x00000001, 0xffffffff, result=0xffffffff)
- test_mulh_8 = test_op(Funct3.MULH, 0x00000001, 0x7fffffff, result=0x00000000)
- test_mulh_9 = test_op(Funct3.MULH, 0x00000001, 0x80000000, result=0xffffffff)
-
- test_mulh_10 = test_op(Funct3.MULH, 0xffffffff, 0x00000000, result=0x00000000)
- test_mulh_11 = test_op(Funct3.MULH, 0xffffffff, 0x00000001, result=0xffffffff)
- test_mulh_12 = test_op(Funct3.MULH, 0xffffffff, 0xffffffff, result=0x00000000)
- test_mulh_13 = test_op(Funct3.MULH, 0xffffffff, 0x7fffffff, result=0xffffffff)
- test_mulh_14 = test_op(Funct3.MULH, 0xffffffff, 0x80000000, result=0x00000000)
-
- test_mulh_15 = test_op(Funct3.MULH, 0x7fffffff, 0x00000000, result=0x00000000)
- test_mulh_16 = test_op(Funct3.MULH, 0x7fffffff, 0x00000001, result=0x00000000)
- test_mulh_17 = test_op(Funct3.MULH, 0x7fffffff, 0xffffffff, result=0xffffffff)
- test_mulh_18 = test_op(Funct3.MULH, 0x7fffffff, 0x7fffffff, result=0x3fffffff)
- test_mulh_19 = test_op(Funct3.MULH, 0x7fffffff, 0x80000000, result=0xc0000000)
-
- test_mulh_20 = test_op(Funct3.MULH, 0x80000000, 0x00000000, result=0x00000000)
- test_mulh_21 = test_op(Funct3.MULH, 0x80000000, 0x00000001, result=0xffffffff)
- test_mulh_22 = test_op(Funct3.MULH, 0x80000000, 0xffffffff, result=0x00000000)
- test_mulh_23 = test_op(Funct3.MULH, 0x80000000, 0x7fffffff, result=0xc0000000)
- test_mulh_24 = test_op(Funct3.MULH, 0x80000000, 0x80000000, result=0x40000000)
+ test_mulh_0 = tst_op(Funct3.MULH, 0x00000000,
+ 0x00000000, result=0x00000000)
+ test_mulh_1 = tst_op(Funct3.MULH, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_mulh_2 = tst_op(Funct3.MULH, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_mulh_3 = tst_op(Funct3.MULH, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_mulh_4 = tst_op(Funct3.MULH, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_mulh_5 = tst_op(Funct3.MULH, 0x00000001,
+ 0x00000000, result=0x00000000)
+ test_mulh_6 = tst_op(Funct3.MULH, 0x00000001,
+ 0x00000001, result=0x00000000)
+ test_mulh_7 = tst_op(Funct3.MULH, 0x00000001,
+ 0xffffffff, result=0xffffffff)
+ test_mulh_8 = tst_op(Funct3.MULH, 0x00000001,
+ 0x7fffffff, result=0x00000000)
+ test_mulh_9 = tst_op(Funct3.MULH, 0x00000001,
+ 0x80000000, result=0xffffffff)
+
+ test_mulh_10 = tst_op(Funct3.MULH, 0xffffffff,
+ 0x00000000, result=0x00000000)
+ test_mulh_11 = tst_op(Funct3.MULH, 0xffffffff,
+ 0x00000001, result=0xffffffff)
+ test_mulh_12 = tst_op(Funct3.MULH, 0xffffffff,
+ 0xffffffff, result=0x00000000)
+ test_mulh_13 = tst_op(Funct3.MULH, 0xffffffff,
+ 0x7fffffff, result=0xffffffff)
+ test_mulh_14 = tst_op(Funct3.MULH, 0xffffffff,
+ 0x80000000, result=0x00000000)
+
+ test_mulh_15 = tst_op(Funct3.MULH, 0x7fffffff,
+ 0x00000000, result=0x00000000)
+ test_mulh_16 = tst_op(Funct3.MULH, 0x7fffffff,
+ 0x00000001, result=0x00000000)
+ test_mulh_17 = tst_op(Funct3.MULH, 0x7fffffff,
+ 0xffffffff, result=0xffffffff)
+ test_mulh_18 = tst_op(Funct3.MULH, 0x7fffffff,
+ 0x7fffffff, result=0x3fffffff)
+ test_mulh_19 = tst_op(Funct3.MULH, 0x7fffffff,
+ 0x80000000, result=0xc0000000)
+
+ test_mulh_20 = tst_op(Funct3.MULH, 0x80000000,
+ 0x00000000, result=0x00000000)
+ test_mulh_21 = tst_op(Funct3.MULH, 0x80000000,
+ 0x00000001, result=0xffffffff)
+ test_mulh_22 = tst_op(Funct3.MULH, 0x80000000,
+ 0xffffffff, result=0x00000000)
+ test_mulh_23 = tst_op(Funct3.MULH, 0x80000000,
+ 0x7fffffff, result=0xc0000000)
+ test_mulh_24 = tst_op(Funct3.MULH, 0x80000000,
+ 0x80000000, result=0x40000000)
# MULHSU -------------------------------------------------------------------------
- test_mulhsu_0 = test_op(Funct3.MULHSU, 0x00000000, 0x00000000, result=0x00000000)
- test_mulhsu_1 = test_op(Funct3.MULHSU, 0x00000000, 0x00000001, result=0x00000000)
- test_mulhsu_2 = test_op(Funct3.MULHSU, 0x00000000, 0xffffffff, result=0x00000000)
- test_mulhsu_3 = test_op(Funct3.MULHSU, 0x00000000, 0x7fffffff, result=0x00000000)
- test_mulhsu_4 = test_op(Funct3.MULHSU, 0x00000000, 0x80000000, result=0x00000000)
-
- test_mulhsu_5 = test_op(Funct3.MULHSU, 0x00000001, 0x00000000, result=0x00000000)
- test_mulhsu_6 = test_op(Funct3.MULHSU, 0x00000001, 0x00000001, result=0x00000000)
- test_mulhsu_7 = test_op(Funct3.MULHSU, 0x00000001, 0xffffffff, result=0x00000000)
- test_mulhsu_8 = test_op(Funct3.MULHSU, 0x00000001, 0x7fffffff, result=0x00000000)
- test_mulhsu_9 = test_op(Funct3.MULHSU, 0x00000001, 0x80000000, result=0x00000000)
-
- test_mulhsu_10 = test_op(Funct3.MULHSU, 0xffffffff, 0x00000000, result=0x00000000)
- test_mulhsu_11 = test_op(Funct3.MULHSU, 0xffffffff, 0x00000001, result=0xffffffff)
- test_mulhsu_12 = test_op(Funct3.MULHSU, 0xffffffff, 0xffffffff, result=0xffffffff)
- test_mulhsu_13 = test_op(Funct3.MULHSU, 0xffffffff, 0x7fffffff, result=0xffffffff)
- test_mulhsu_14 = test_op(Funct3.MULHSU, 0xffffffff, 0x80000000, result=0xffffffff)
-
- test_mulhsu_15 = test_op(Funct3.MULHSU, 0x7fffffff, 0x00000000, result=0x00000000)
- test_mulhsu_16 = test_op(Funct3.MULHSU, 0x7fffffff, 0x00000001, result=0x00000000)
- test_mulhsu_17 = test_op(Funct3.MULHSU, 0x7fffffff, 0xffffffff, result=0x7ffffffe)
- test_mulhsu_18 = test_op(Funct3.MULHSU, 0x7fffffff, 0x7fffffff, result=0x3fffffff)
- test_mulhsu_19 = test_op(Funct3.MULHSU, 0x7fffffff, 0x80000000, result=0x3fffffff)
-
- test_mulhsu_20 = test_op(Funct3.MULHSU, 0x80000000, 0x00000000, result=0x00000000)
- test_mulhsu_21 = test_op(Funct3.MULHSU, 0x80000000, 0x00000001, result=0xffffffff)
- test_mulhsu_22 = test_op(Funct3.MULHSU, 0x80000000, 0xffffffff, result=0x80000000)
- test_mulhsu_23 = test_op(Funct3.MULHSU, 0x80000000, 0x7fffffff, result=0xc0000000)
- test_mulhsu_24 = test_op(Funct3.MULHSU, 0x80000000, 0x80000000, result=0xc0000000)
+ test_mulhsu_0 = tst_op(Funct3.MULHSU, 0x00000000,
+ 0x00000000, result=0x00000000)
+ test_mulhsu_1 = tst_op(Funct3.MULHSU, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_mulhsu_2 = tst_op(Funct3.MULHSU, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_mulhsu_3 = tst_op(Funct3.MULHSU, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_mulhsu_4 = tst_op(Funct3.MULHSU, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_mulhsu_5 = tst_op(Funct3.MULHSU, 0x00000001,
+ 0x00000000, result=0x00000000)
+ test_mulhsu_6 = tst_op(Funct3.MULHSU, 0x00000001,
+ 0x00000001, result=0x00000000)
+ test_mulhsu_7 = tst_op(Funct3.MULHSU, 0x00000001,
+ 0xffffffff, result=0x00000000)
+ test_mulhsu_8 = tst_op(Funct3.MULHSU, 0x00000001,
+ 0x7fffffff, result=0x00000000)
+ test_mulhsu_9 = tst_op(Funct3.MULHSU, 0x00000001,
+ 0x80000000, result=0x00000000)
+
+ test_mulhsu_10 = tst_op(Funct3.MULHSU, 0xffffffff,
+ 0x00000000, result=0x00000000)
+ test_mulhsu_11 = tst_op(Funct3.MULHSU, 0xffffffff,
+ 0x00000001, result=0xffffffff)
+ test_mulhsu_12 = tst_op(Funct3.MULHSU, 0xffffffff,
+ 0xffffffff, result=0xffffffff)
+ test_mulhsu_13 = tst_op(Funct3.MULHSU, 0xffffffff,
+ 0x7fffffff, result=0xffffffff)
+ test_mulhsu_14 = tst_op(Funct3.MULHSU, 0xffffffff,
+ 0x80000000, result=0xffffffff)
+
+ test_mulhsu_15 = tst_op(Funct3.MULHSU, 0x7fffffff,
+ 0x00000000, result=0x00000000)
+ test_mulhsu_16 = tst_op(Funct3.MULHSU, 0x7fffffff,
+ 0x00000001, result=0x00000000)
+ test_mulhsu_17 = tst_op(Funct3.MULHSU, 0x7fffffff,
+ 0xffffffff, result=0x7ffffffe)
+ test_mulhsu_18 = tst_op(Funct3.MULHSU, 0x7fffffff,
+ 0x7fffffff, result=0x3fffffff)
+ test_mulhsu_19 = tst_op(Funct3.MULHSU, 0x7fffffff,
+ 0x80000000, result=0x3fffffff)
+
+ test_mulhsu_20 = tst_op(Funct3.MULHSU, 0x80000000,
+ 0x00000000, result=0x00000000)
+ test_mulhsu_21 = tst_op(Funct3.MULHSU, 0x80000000,
+ 0x00000001, result=0xffffffff)
+ test_mulhsu_22 = tst_op(Funct3.MULHSU, 0x80000000,
+ 0xffffffff, result=0x80000000)
+ test_mulhsu_23 = tst_op(Funct3.MULHSU, 0x80000000,
+ 0x7fffffff, result=0xc0000000)
+ test_mulhsu_24 = tst_op(Funct3.MULHSU, 0x80000000,
+ 0x80000000, result=0xc0000000)
# MULHU --------------------------------------------------------------------------
- test_mulhu_0 = test_op(Funct3.MULHU, 0x00000000, 0x00000000, result=0x00000000)
- test_mulhu_1 = test_op(Funct3.MULHU, 0x00000000, 0x00000001, result=0x00000000)
- test_mulhu_2 = test_op(Funct3.MULHU, 0x00000000, 0xffffffff, result=0x00000000)
- test_mulhu_3 = test_op(Funct3.MULHU, 0x00000000, 0x7fffffff, result=0x00000000)
- test_mulhu_4 = test_op(Funct3.MULHU, 0x00000000, 0x80000000, result=0x00000000)
-
- test_mulhu_5 = test_op(Funct3.MULHU, 0x00000001, 0x00000000, result=0x00000000)
- test_mulhu_6 = test_op(Funct3.MULHU, 0x00000001, 0x00000001, result=0x00000000)
- test_mulhu_7 = test_op(Funct3.MULHU, 0x00000001, 0xffffffff, result=0x00000000)
- test_mulhu_8 = test_op(Funct3.MULHU, 0x00000001, 0x7fffffff, result=0x00000000)
- test_mulhu_9 = test_op(Funct3.MULHU, 0x00000001, 0x80000000, result=0x00000000)
-
- test_mulhu_10 = test_op(Funct3.MULHU, 0xffffffff, 0x00000000, result=0x00000000)
- test_mulhu_11 = test_op(Funct3.MULHU, 0xffffffff, 0x00000001, result=0x00000000)
- test_mulhu_12 = test_op(Funct3.MULHU, 0xffffffff, 0xffffffff, result=0xfffffffe)
- test_mulhu_13 = test_op(Funct3.MULHU, 0xffffffff, 0x7fffffff, result=0x7ffffffe)
- test_mulhu_14 = test_op(Funct3.MULHU, 0xffffffff, 0x80000000, result=0x7fffffff)
-
- test_mulhu_15 = test_op(Funct3.MULHU, 0x7fffffff, 0x00000000, result=0x00000000)
- test_mulhu_16 = test_op(Funct3.MULHU, 0x7fffffff, 0x00000001, result=0x00000000)
- test_mulhu_17 = test_op(Funct3.MULHU, 0x7fffffff, 0xffffffff, result=0x7ffffffe)
- test_mulhu_18 = test_op(Funct3.MULHU, 0x7fffffff, 0x7fffffff, result=0x3fffffff)
- test_mulhu_19 = test_op(Funct3.MULHU, 0x7fffffff, 0x80000000, result=0x3fffffff)
-
- test_mulhu_20 = test_op(Funct3.MULHU, 0x80000000, 0x00000000, result=0x00000000)
- test_mulhu_21 = test_op(Funct3.MULHU, 0x80000000, 0x00000001, result=0x00000000)
- test_mulhu_22 = test_op(Funct3.MULHU, 0x80000000, 0xffffffff, result=0x7fffffff)
- test_mulhu_23 = test_op(Funct3.MULHU, 0x80000000, 0x7fffffff, result=0x3fffffff)
- test_mulhu_24 = test_op(Funct3.MULHU, 0x80000000, 0x80000000, result=0x40000000)
+ test_mulhu_0 = tst_op(Funct3.MULHU, 0x00000000,
+ 0x00000000, result=0x00000000)
+ test_mulhu_1 = tst_op(Funct3.MULHU, 0x00000000,
+ 0x00000001, result=0x00000000)
+ test_mulhu_2 = tst_op(Funct3.MULHU, 0x00000000,
+ 0xffffffff, result=0x00000000)
+ test_mulhu_3 = tst_op(Funct3.MULHU, 0x00000000,
+ 0x7fffffff, result=0x00000000)
+ test_mulhu_4 = tst_op(Funct3.MULHU, 0x00000000,
+ 0x80000000, result=0x00000000)
+
+ test_mulhu_5 = tst_op(Funct3.MULHU, 0x00000001,
+ 0x00000000, result=0x00000000)
+ test_mulhu_6 = tst_op(Funct3.MULHU, 0x00000001,
+ 0x00000001, result=0x00000000)
+ test_mulhu_7 = tst_op(Funct3.MULHU, 0x00000001,
+ 0xffffffff, result=0x00000000)
+ test_mulhu_8 = tst_op(Funct3.MULHU, 0x00000001,
+ 0x7fffffff, result=0x00000000)
+ test_mulhu_9 = tst_op(Funct3.MULHU, 0x00000001,
+ 0x80000000, result=0x00000000)
+
+ test_mulhu_10 = tst_op(Funct3.MULHU, 0xffffffff,
+ 0x00000000, result=0x00000000)
+ test_mulhu_11 = tst_op(Funct3.MULHU, 0xffffffff,
+ 0x00000001, result=0x00000000)
+ test_mulhu_12 = tst_op(Funct3.MULHU, 0xffffffff,
+ 0xffffffff, result=0xfffffffe)
+ test_mulhu_13 = tst_op(Funct3.MULHU, 0xffffffff,
+ 0x7fffffff, result=0x7ffffffe)
+ test_mulhu_14 = tst_op(Funct3.MULHU, 0xffffffff,
+ 0x80000000, result=0x7fffffff)
+
+ test_mulhu_15 = tst_op(Funct3.MULHU, 0x7fffffff,
+ 0x00000000, result=0x00000000)
+ test_mulhu_16 = tst_op(Funct3.MULHU, 0x7fffffff,
+ 0x00000001, result=0x00000000)
+ test_mulhu_17 = tst_op(Funct3.MULHU, 0x7fffffff,
+ 0xffffffff, result=0x7ffffffe)
+ test_mulhu_18 = tst_op(Funct3.MULHU, 0x7fffffff,
+ 0x7fffffff, result=0x3fffffff)
+ test_mulhu_19 = tst_op(Funct3.MULHU, 0x7fffffff,
+ 0x80000000, result=0x3fffffff)
+
+ test_mulhu_20 = tst_op(Funct3.MULHU, 0x80000000,
+ 0x00000000, result=0x00000000)
+ test_mulhu_21 = tst_op(Funct3.MULHU, 0x80000000,
+ 0x00000001, result=0x00000000)
+ test_mulhu_22 = tst_op(Funct3.MULHU, 0x80000000,
+ 0xffffffff, result=0x7fffffff)
+ test_mulhu_23 = tst_op(Funct3.MULHU, 0x80000000,
+ 0x7fffffff, result=0x3fffffff)
+ test_mulhu_24 = tst_op(Funct3.MULHU, 0x80000000,
+ 0x80000000, result=0x40000000)
from .regfile import DebugRegisterFile
from .wbmaster import wishbone_layout, DebugWishboneMaster
-from jtagtap import JTAGTap
+# FIXME: figure out where JTAGTap is
+# from jtagtap import JTAGTap
+
+
+class JTAGTap:
+ def __init__(self):
+ raise NotImplementedError(
+ "jtagtap package not found: figure out where JTAGTap is")
+
__all__ = ["DebugUnit"]
def elaborate(self, platform):
m = Module()
- tap = m.submodules.tap = JTAGTap(jtag_regs)
- regfile = m.submodules.regfile = DebugRegisterFile(tap.regs[JTAGReg.DMI])
+ tap = m.submodules.tap = JTAGTap(jtag_regs)
+ regfile = m.submodules.regfile = DebugRegisterFile(
+ tap.regs[JTAGReg.DMI])
controller = m.submodules.controller = DebugController(regfile)
- wbmaster = m.submodules.wbmaster = DebugWishboneMaster(regfile)
+ wbmaster = m.submodules.wbmaster = DebugWishboneMaster(regfile)
m.d.comb += [
tap.port.connect(self.jtag),
- tap.regs[JTAGReg.IDCODE].r.eq(0x10e31913), # Usurpate a Spike core for now.
- tap.regs[JTAGReg.DTMCS].r.eq(0x61) # (abits=6, version=1) TODO
+ # Usurpate a Spike core for now.
+ tap.regs[JTAGReg.IDCODE].r.eq(0x10e31913),
+ tap.regs[JTAGReg.DTMCS].r.eq(0x61) # (abits=6, version=1) TODO
]
m.d.comb += [
-from nmigen import Elaboratable, Module, Signal, Cat, Mux, C
+from nmigen import Elaboratable, Module, Signal, Cat, Mux, C, signed
from ..isa import Funct3
class MultiplierInterface:
def __init__(self):
- self.x_op = Signal(3)
- self.x_src1 = Signal(32)
- self.x_src2 = Signal(32)
- self.x_stall = Signal()
- self.m_stall = Signal()
+ self.x_op = Signal(3)
+ self.x_src1 = Signal(32)
+ self.x_src2 = Signal(32)
+ self.x_stall = Signal()
+ self.m_stall = Signal()
self.w_result = Signal(32)
m.d.comb += [
x_low.eq(self.x_op == Funct3.MUL),
- x_src1_signed.eq((self.x_op == Funct3.MULH) | (self.x_op == Funct3.MULHSU)),
+ x_src1_signed.eq((self.x_op == Funct3.MULH) |
+ (self.x_op == Funct3.MULHSU)),
x_src2_signed.eq(self.x_op == Funct3.MULH)
]
# As per the RVFI specification (§ "Alternative Arithmetic Operations").
# https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md
with m.Case(Funct3.MUL):
- m.d.comb += x_result.eq((self.x_src1 + self.x_src2) ^ C(0x5876063e))
+ m.d.comb += x_result.eq((self.x_src1 +
+ self.x_src2) ^ C(0x5876063e))
with m.Case(Funct3.MULH):
- m.d.comb += x_result.eq((self.x_src1 + self.x_src2) ^ C(0xf6583fb7))
+ m.d.comb += x_result.eq((self.x_src1 +
+ self.x_src2) ^ C(0xf6583fb7))
with m.Case(Funct3.MULHSU):
- m.d.comb += x_result.eq((self.x_src1 - self.x_src2) ^ C(0xecfbe137))
+ m.d.comb += x_result.eq((self.x_src1 -
+ self.x_src2) ^ C(0xecfbe137))
with m.Case(Funct3.MULHU):
- m.d.comb += x_result.eq((self.x_src1 + self.x_src2) ^ C(0x949ce5e8))
+ m.d.comb += x_result.eq((self.x_src1 +
+ self.x_src2) ^ C(0x949ce5e8))
with m.If(~self.x_stall):
m.d.sync += m_result.eq(x_result)
* wr_pend is set False for the majority of uses: however for
use in a STORE Function Unit it is set to True
"""
+
def __init__(self, wid, shadow_wid=0, n_dests=1, wr_pend=False):
self.reg_width = wid
self.n_dests = n_dests
# inputs
if n_dests > 1:
- self.rfile_sel_i = Signal(max=n_dests, reset_less=True)
+ self.rfile_sel_i = Signal(range(n_dests), reset_less=True)
else:
- self.rfile_sel_i = Const(0) # no selection. gets Array[0]
- self.dest_i = Signal(max=wid, reset_less=True) # Dest R# in (top)
- self.src1_i = Signal(max=wid, reset_less=True) # oper1 R# in (top)
- self.src2_i = Signal(max=wid, reset_less=True) # oper2 R# in (top)
+ self.rfile_sel_i = Const(0) # no selection. gets Array[0]
+ self.dest_i = Signal(range(wid), reset_less=True) # Dest R# in (top)
+ self.src1_i = Signal(range(wid), reset_less=True) # oper1 R# in (top)
+ self.src2_i = Signal(range(wid), reset_less=True) # oper2 R# in (top)
self.issue_i = Signal(reset_less=True) # Issue in (top)
- self.go_wr_i = Signal(reset_less=True) # Go Write in (left)
+ self.go_wr_i = Signal(reset_less=True) # Go Write in (left)
self.go_rd_i = Signal(reset_less=True) # Go Read in (left)
self.req_rel_i = Signal(reset_less=True) # request release (left)
- self.g_xx_pend_i = Array(Signal(wid, reset_less=True, name="g_pend_i") \
- for i in range(n_dests)) # global rd (right)
- self.g_wr_pend_i = Signal(wid, reset_less=True) # global wr (right)
+ self.g_xx_pend_i = Array(Signal(wid, reset_less=True, name="g_pend_i")
+ for i in range(n_dests)) # global rd (right)
+ self.g_wr_pend_i = Signal(wid, reset_less=True) # global wr (right)
if shadow_wid:
self.shadow_i = Signal(shadow_wid, reset_less=True)
- self.s_fail_i = Signal(shadow_wid, reset_less=True)
- self.s_good_i = Signal(shadow_wid, reset_less=True)
- self.go_die_o = Signal(reset_less=True)
+ self.s_fail_i = Signal(shadow_wid, reset_less=True)
+ self.s_good_i = Signal(shadow_wid, reset_less=True)
+ self.go_die_o = Signal(reset_less=True)
# outputs
- self.readable_o = Signal(reset_less=True) # Readable out (right)
- self.writable_o = Array(Signal(reset_less=True, name="writable_o") \
- for i in range(n_dests)) # writable out (right)
- self.busy_o = Signal(reset_less=True) # busy out (left)
+ self.readable_o = Signal(reset_less=True) # Readable out (right)
+ self.writable_o = Array(Signal(reset_less=True, name="writable_o")
+ for i in range(n_dests)) # writable out (right)
+ self.busy_o = Signal(reset_less=True) # busy out (left)
- self.src1_pend_o = Signal(wid, reset_less=True) # src1 pending
- self.src2_pend_o = Signal(wid, reset_less=True) # src1 pending
- self.rd_pend_o = Signal(wid, reset_less=True) # rd pending (right)
- self.xx_pend_o = Array(Signal(wid, reset_less=True, name="pend_o") \
- for i in range(n_dests))# wr pending (right)
+ self.src1_pend_o = Signal(wid, reset_less=True) # src1 pending
+ self.src2_pend_o = Signal(wid, reset_less=True) # src1 pending
+ self.rd_pend_o = Signal(wid, reset_less=True) # rd pending (right)
+ self.xx_pend_o = Array(Signal(wid, reset_less=True, name="pend_o")
+ for i in range(n_dests)) # wr pending (right)
def elaborate(self, platform):
m = Module()
for i in range(self.n_dests):
m.d.comb += self.xx_pend_o[i].eq(0) # initialise all array
- m.d.comb += self.writable_o[i].eq(0) # to zero
- m.d.comb += self.readable_o.eq(0) # to zero
+ m.d.comb += self.writable_o[i].eq(0) # to zero
+ m.d.comb += self.readable_o.eq(0) # to zero
# go_wr latch: reset on go_wr HI, set on issue
m.d.comb += wr_l.s.eq(self.issue_i)
m.d.comb += rd_l.r.eq(self.go_rd_i | recover)
# latch/registers for dest / src1 / src2
- dest_r = Signal(max=self.reg_width, reset_less=True)
- src1_r = Signal(max=self.reg_width, reset_less=True)
- src2_r = Signal(max=self.reg_width, reset_less=True)
+ dest_r = Signal(range(self.reg_width), reset_less=True)
+ src1_r = Signal(range(self.reg_width), reset_less=True)
+ src2_r = Signal(range(self.reg_width), reset_less=True)
# XXX latch based on *issue* rather than !latch (as in book)
- latchregister(m, self.dest_i, dest_r, self.issue_i) #wr_l.qn)
- latchregister(m, self.src1_i, src1_r, self.issue_i) #wr_l.qn)
- latchregister(m, self.src2_i, src2_r, self.issue_i) #wr_l.qn)
+ latchregister(m, self.dest_i, dest_r, self.issue_i) # wr_l.qn)
+ latchregister(m, self.src1_i, src1_r, self.issue_i) # wr_l.qn)
+ latchregister(m, self.src2_i, src2_r, self.issue_i) # wr_l.qn)
# dest decoder (use dest reg as input): write-pending out
m.d.comb += dest_d.i.eq(dest_r)
- m.d.comb += dest_d.n.eq(wr_l.qn) # decode is inverted
- m.d.comb += self.busy_o.eq(wr_l.q) # busy if set
+ m.d.comb += dest_d.n.eq(wr_l.qn) # decode is inverted
+ m.d.comb += self.busy_o.eq(wr_l.q) # busy if set
m.d.comb += xx_pend_o.eq(dest_d.o)
# src1/src2 decoder (use src1/2 regs as input): read-pending out
m.d.comb += src1_d.i.eq(src1_r)
- m.d.comb += src1_d.n.eq(rd_l.qn) # decode is inverted
+ m.d.comb += src1_d.n.eq(rd_l.qn) # decode is inverted
m.d.comb += src2_d.i.eq(src2_r)
- m.d.comb += src2_d.n.eq(rd_l.qn) # decode is inverted
+ m.d.comb += src2_d.n.eq(rd_l.qn) # decode is inverted
m.d.comb += self.src1_pend_o.eq(src1_d.o)
m.d.comb += self.src2_pend_o.eq(src2_d.o)
m.d.comb += self.rd_pend_o.eq(src1_d.o | src2_d.o)
* when rfile_sel_i == 0, int_wr_pend_o is set
* when rfile_sel_i == 1, fp_wr_pend_o is set
"""
+
def __init__(self, wid, shadow_wid=0):
FnUnit.__init__(self, wid, shadow_wid, n_dests=2)
self.int_rd_pend_o = self.rd_pend_o
* when rfile_sel_i == 1, fp_wr_pend_o is set
*
"""
+
def __init__(self, wid, shadow_wid=0):
FnUnit.__init__(self, wid, shadow_wid, n_dests=2, wr_pend=True)
self.int_rd_pend_o = self.rd_pend_o # 1st int read-pending vector
- self.int2_rd_pend_o = self.xx_pend_o[0] # 2nd int read-pending vector
+ self.int2_rd_pend_o = self.xx_pend_o[0] # 2nd int read-pending vector
self.fp_rd_pend_o = self.xx_pend_o[1] # 1x FP read-pending vector
# yes overwrite FnUnit base class g_wr_pend_i vector
self.g_int_wr_pend_i = self.g_wr_pend_i = self.g_xx_pend_i[0]
self.fp_writable_o.name = "fp_writable_o"
-
def int_fn_unit_sim(dut):
yield dut.dest_i.eq(1)
yield dut.issue_i.eq(1)
yield dut.go_wr_i.eq(0)
yield
+
def test_int_fn_unit():
dut = FnUnit(32, 2, 2)
vl = rtlil.convert(dut, ports=dut.ports())
run_simulation(dut, int_fn_unit_sim(dut), vcd_name='test_fn_unit.vcd')
+
if __name__ == '__main__':
test_int_fn_unit()
from nmigen.cli import verilog, rtlil
from nmigen import Module, Signal, Elaboratable, Array, Cat, Const
-from ldst_dep_cell import LDSTDepCell
+from .ldst_dep_cell import LDSTDepCell
class LDSTDepMatrix(Elaboratable):
fashion, ORing together. the OR gate from the dependency cell is
here.
"""
+
def __init__(self, n_ldst):
self.n_ldst = n_ldst # X and Y (FUs)
self.ld_pend_i = Signal(n_ldst, reset_less=True) # load pending in
self.st_pend_i = Signal(n_ldst, reset_less=True) # store pending in
- self.issue_i = Signal(n_ldst, reset_less=True) # Issue in
- self.go_die_i = Signal(n_ldst, reset_less=True) # Die/Reset in
+ self.issue_i = Signal(n_ldst, reset_less=True) # Issue in
+ self.go_die_i = Signal(n_ldst, reset_less=True) # Die/Reset in
- self.load_hit_i = Signal(n_ldst, reset_less=True) # load hit in
- self.stwd_hit_i = Signal(n_ldst, reset_less=True) # store w/data hit in
+ self.load_hit_i = Signal(n_ldst, reset_less=True) # load hit in
+ self.stwd_hit_i = Signal(
+ n_ldst, reset_less=True) # store w/data hit in
# outputs
- self.ld_hold_st_o = Signal(n_ldst, reset_less=True) # load holds st out
- self.st_hold_ld_o = Signal(n_ldst, reset_less=True) # st holds load out
+ self.ld_hold_st_o = Signal(
+ n_ldst, reset_less=True) # load holds st out
+ self.st_hold_ld_o = Signal(
+ n_ldst, reset_less=True) # st holds load out
def elaborate(self, platform):
m = Module()
dc.stwd_hit_i.eq(self.stwd_hit_i),
dc.load_v_i.eq(self.ld_pend_i),
dc.stor_v_i.eq(self.st_pend_i),
- ]
+ ]
# connect cell inputs using Cat(*list_of_stuff)
m.d.comb += [Cat(*issue_l).eq(self.issue_i),
Cat(*go_die_l).eq(self.go_die_i),
- ]
+ ]
# connect the load-hold-store / store-hold-load OR-accumulated outputs
m.d.comb += self.ld_hold_st_o.eq(Cat(*lhs_l))
m.d.comb += self.st_hold_ld_o.eq(Cat(*shl_l))
stor_h_l.append(dc.stor_h_i)
m.d.comb += [Cat(*load_h_l).eq(self.ld_pend_i),
Cat(*stor_h_l).eq(self.st_pend_i),
- ]
+ ]
return m
def ports(self):
return list(self)
+
def d_matrix_sim(dut):
""" XXX TODO
"""
yield dut.go_wr_i.eq(0)
yield
+
def test_d_matrix():
dut = LDSTDepMatrix(n_ldst=4)
vl = rtlil.convert(dut, ports=dut.ports())
run_simulation(dut, d_matrix_sim(dut), vcd_name='test_ld_st_matrix.vcd')
+
if __name__ == '__main__':
test_d_matrix()
from nmigen.cli import verilog, rtlil
from nmigen import Module, Const, Signal, Array, Cat, Elaboratable
-from regfile.regfile import RegFileArray, treereduce
+from soc.regfile.regfile import RegFileArray, treereduce
from soc.scoreboard.global_pending import GlobalPending
from soc.scoreboard.group_picker import GroupPicker
from soc.scoreboard.issue_unit import IssueUnitGroup, IssueUnitArray, RegDecode
from copy import deepcopy
from math import log
+# FIXME: fixed up imports
+from ..experiment.score6600 import IssueToScoreboard, RegSim, instr_q, wait_for_busy_clear, wait_for_issue, CompUnitALUs, CompUnitBR, CompUnitsBase
+
class Memory(Elaboratable):
def __init__(self, regwid, addrw):
self.ddepth = regwid/8
- depth = (1<<addrw) / self.ddepth
- self.adr = Signal(addrw)
+ depth = (1 << addrw) / self.ddepth
+ self.adr = Signal(addrw)
self.dat_r = Signal(regwid)
self.dat_w = Signal(regwid)
- self.we = Signal()
- self.mem = Memory(width=regwid, depth=depth, init=range(0, depth))
+ self.we = Signal()
+ self.mem = Memory(width=regwid, depth=depth, init=range(0, depth))
def elaborate(self, platform):
m = Module()
m.submodules.rdport = rdport = self.mem.read_port()
m.submodules.wrport = wrport = self.mem.write_port()
m.d.comb += [
- rdport.addr.eq(self.adr[self.ddepth:]), # ignore low bits
+ rdport.addr.eq(self.adr[self.ddepth:]), # ignore low bits
self.dat_r.eq(rdport.data),
wrport.addr.eq(self.adr),
wrport.data.eq(self.dat_w),
def __init__(self, regwid, addrw):
self.regwid = regwid
self.ddepth = regwid//8
- depth = (1<<addrw) // self.ddepth
+ depth = (1 << addrw) // self.ddepth
self.mem = list(range(0, depth))
def ld(self, addr):
- return self.mem[addr>>self.ddepth]
+ return self.mem[addr >> self.ddepth]
def st(self, addr, data):
- self.mem[addr>>self.ddepth] = data & ((1<<self.regwid)-1)
+ self.mem[addr >> self.ddepth] = data & ((1 << self.regwid)-1)
class Scoreboard(Elaboratable):
self.br_imm_i = Signal(rwid, reset_less=True)
# inputs
- self.int_dest_i = Signal(max=n_regs, reset_less=True) # Dest R# in
- self.int_src1_i = Signal(max=n_regs, reset_less=True) # oper1 R# in
- self.int_src2_i = Signal(max=n_regs, reset_less=True) # oper2 R# in
- self.reg_enable_i = Signal(reset_less=True) # enable reg decode
+ self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
+ self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
+ self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
+ self.reg_enable_i = Signal(reset_less=True) # enable reg decode
# outputs
- self.issue_o = Signal(reset_less=True) # instruction was accepted
- self.busy_o = Signal(reset_less=True) # at least one CU is busy
+ self.issue_o = Signal(reset_less=True) # instruction was accepted
+ self.busy_o = Signal(reset_less=True) # at least one CU is busy
# for branch speculation experiment. branch_direction = 0 if
# the branch hasn't been met yet. 1 indicates "success", 2 is "fail"
cua = CompUnitALUs(self.rwid, 3)
cub = CompUnitBR(self.rwid, 3)
m.submodules.cu = cu = CompUnitsBase(self.rwid, [cua, cub])
- bgt = cub.bgt # get at the branch computation unit
+ bgt = cub.bgt # get at the branch computation unit
br1 = cub.br1
# Int FUs
# Count of number of FUs
n_intfus = n_int_alus
- n_fp_fus = 0 # for now
+ n_fp_fus = 0 # for now
# Integer Priority Picker 1: Adder + Subtractor
- intpick1 = GroupPicker(n_intfus) # picks between add, sub, mul and shf
+ intpick1 = GroupPicker(n_intfus) # picks between add, sub, mul and shf
m.submodules.intpick1 = intpick1
# INT/FP Issue Unit
# allow/cancel can be issued as appropriate.
m.submodules.specrec = bspec = BranchSpeculationRecord(n_intfus)
- #---------
+ # ---------
# ok start wiring things together...
# "now hear de word of de looord... dem bones dem bones dem dryy bones"
# https://www.youtube.com/watch?v=pYb8Wm6-QfA
- #---------
+ # ---------
- #---------
+ # ---------
# Issue Unit is where it starts. set up some in/outs for this module
- #---------
- comb += [ regdecode.dest_i.eq(self.int_dest_i),
- regdecode.src1_i.eq(self.int_src1_i),
- regdecode.src2_i.eq(self.int_src2_i),
- regdecode.enable_i.eq(self.reg_enable_i),
- self.issue_o.eq(issueunit.issue_o)
- ]
+ # ---------
+ comb += [regdecode.dest_i.eq(self.int_dest_i),
+ regdecode.src1_i.eq(self.int_src1_i),
+ regdecode.src2_i.eq(self.int_src2_i),
+ regdecode.enable_i.eq(self.reg_enable_i),
+ self.issue_o.eq(issueunit.issue_o)
+ ]
# take these to outside (issue needs them)
comb += cua.oper_i.eq(self.alu_oper_i)
comb += issueunit.busy_i.eq(cu.busy_o)
comb += self.busy_o.eq(cu.busy_o.bool())
- #---------
+ # ---------
# merge shadow matrices outputs
- #---------
+ # ---------
# these are explained in ShadowMatrix docstring, and are to be
# connected to the FUReg and FUFU Matrices, to get them to reset
comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o)
comb += shreset.eq(bspec.match_g_o | bspec.match_f_o)
- #---------
+ # ---------
# connect fu-fu matrix
- #---------
+ # ---------
# Group Picker... done manually for now.
go_rd_o = intpick1.go_rd_o
go_wr_i = intfus.go_wr_i
go_die_i = intfus.go_die_i
# NOTE: connect to the shadowed versions so that they can "die" (reset)
- comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
- comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
- comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
+ comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
+ comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
+ comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
# Connect Picker
- #---------
+ # ---------
comb += intpick1.rd_rel_i[0:n_intfus].eq(cu.rd_rel_o[0:n_intfus])
comb += intpick1.req_rel_i[0:n_intfus].eq(cu.req_rel_o[0:n_intfus])
int_rd_o = intfus.readable_o
comb += intpick1.readable_i[0:n_intfus].eq(int_rd_o[0:n_intfus])
comb += intpick1.writable_i[0:n_intfus].eq(int_wr_o[0:n_intfus])
- #---------
+ # ---------
# Shadow Matrix
- #---------
+ # ---------
comb += shadows.issue_i.eq(fn_issue_o)
#comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
- #---------
+ # ---------
# NOTE; this setup is for the instruction order preservation...
# connect shadows / go_dies to Computation Units
for i in range(n_intfus):
comb += shadows.shadow_i[i][0:n_intfus].eq(prev_shadow)
- #---------
+ # ---------
# ... and this is for branch speculation. it uses the extra bit
# tacked onto the ShadowMatrix (hence shadow_wid=n_intfus+1)
# only needs to set shadow_i, s_fail_i and s_good_i
with m.If(bactive & (self.branch_succ_i | self.branch_fail_i)):
comb += bshadow.issue_i.eq(fn_issue_o)
for i in range(n_intfus):
- with m.If(fn_issue_o & (Const(1<<i))):
+ with m.If(fn_issue_o & (Const(1 << i))):
comb += bshadow.shadow_i[i][0].eq(1)
# finally, we need an indicator to the test infrastructure as to
# ... or it didn't
comb += bshadow.s_fail_i[i][0].eq(bspec.match_f_o[i])
- #---------
+ # ---------
# Connect Register File(s)
- #---------
+ # ---------
comb += int_dest.wen.eq(intfus.dest_rsel_o)
comb += int_src1.ren.eq(intfus.src1_rsel_o)
comb += int_src2.ren.eq(intfus.src2_rsel_o)
return list(self)
-
-
def int_instr(dut, op, imm, src1, src2, dest, branch_success, branch_fail):
yield from disable_issue(dut)
yield dut.int_dest_i.eq(dest)
yield dut.int_src1_i.eq(src1)
yield dut.int_src2_i.eq(src2)
- if (op & (0x3<<2)) != 0: # branch
+ if (op & (0x3 << 2)) != 0: # branch
yield dut.brissue.insn_i.eq(1)
yield dut.br_oper_i.eq(Const(op & 0x3, 2))
yield dut.br_imm_i.eq(imm)
reg = yield dut.intregs.regs[rnum].reg
rs.append("%x" % reg)
rnums = map(str, rnums)
- print ("reg %s: %s" % (','.join(rnums), ','.join(rs)))
+ print("reg %s: %s" % (','.join(rnums), ','.join(rs)))
def create_random_ops(dut, n_ops, shadowing=False, max_opnums=3):
for i in range(n_ops):
src1 = randint(1, dut.n_regs-1)
src2 = randint(1, dut.n_regs-1)
- imm = randint(1, (1<<dut.rwid)-1)
+ imm = randint(1, (1 << dut.rwid)-1)
dest = randint(1, dut.n_regs-1)
op = randint(0, max_opnums)
- opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
+ opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
if shadowing:
insts.append((src1, src2, dest, op, opi, imm, (0, 0)))
return insts
-
def scoreboard_sim(dut, alusim):
seed(0)
# set random values in the registers
for i in range(1, dut.n_regs):
- val = randint(0, (1<<alusim.rwidth)-1)
+ val = randint(0, (1 << alusim.rwidth)-1)
#val = 31+i*3
#val = i
yield dut.intregs.regs[i].reg.eq(val)
instrs = create_random_ops(dut, 15, True, 4)
if False:
- instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
+ instrs.append((1, 2, 2, 1, 1, 20, (0, 0)))
if False:
- instrs.append( (7, 3, 2, 4, (0, 0)) )
- instrs.append( (7, 6, 6, 2, (0, 0)) )
- instrs.append( (1, 7, 2, 2, (0, 0)) )
+ instrs.append((7, 3, 2, 4, (0, 0)))
+ instrs.append((7, 6, 6, 2, (0, 0)))
+ instrs.append((1, 7, 2, 2, (0, 0)))
if False:
instrs.append((2, 3, 3, 0, 0, 0, (0, 0)))
instrs.append((3, 5, 5, 0, 0, 0, (0, 0)))
if False:
- instrs.append( (3, 3, 4, 0, 0, 13979, (0, 0)))
- instrs.append( (6, 4, 1, 2, 0, 40976, (0, 0)))
- instrs.append( (1, 4, 7, 4, 1, 23652, (0, 0)))
+ instrs.append((3, 3, 4, 0, 0, 13979, (0, 0)))
+ instrs.append((6, 4, 1, 2, 0, 40976, (0, 0)))
+ instrs.append((1, 4, 7, 4, 1, 23652, (0, 0)))
if False:
instrs.append((5, 6, 2, 1))
if False:
# Write-after-Write Hazard
- instrs.append( (3, 6, 7, 2) )
- instrs.append( (4, 4, 7, 1) )
+ instrs.append((3, 6, 7, 2))
+ instrs.append((4, 4, 7, 1))
if False:
# self-read/write-after-write followed by Read-after-Write
if False:
# very weird failure
- instrs.append( (5, 2, 5, 2) )
- instrs.append( (2, 6, 3, 0) )
- instrs.append( (4, 2, 2, 1) )
+ instrs.append((5, 2, 5, 2))
+ instrs.append((2, 6, 3, 0))
+ instrs.append((4, 2, 2, 1))
if False:
v1 = 4
instrs.append((4, 2, 1, 2, (1, 0)))
if False:
- instrs.append( (4, 3, 5, 1, 0, (0, 0)) )
- instrs.append( (5, 2, 3, 1, 0, (0, 0)) )
- instrs.append( (7, 1, 5, 2, 0, (0, 0)) )
- instrs.append( (5, 6, 6, 4, 0, (0, 0)) )
- instrs.append( (7, 5, 2, 2, 0, (1, 0)) )
- instrs.append( (1, 7, 5, 0, 0, (0, 1)) )
- instrs.append( (1, 6, 1, 2, 0, (1, 0)) )
- instrs.append( (1, 6, 7, 3, 0, (0, 0)) )
- instrs.append( (6, 7, 7, 0, 0, (0, 0)) )
+ instrs.append((4, 3, 5, 1, 0, (0, 0)))
+ instrs.append((5, 2, 3, 1, 0, (0, 0)))
+ instrs.append((7, 1, 5, 2, 0, (0, 0)))
+ instrs.append((5, 6, 6, 4, 0, (0, 0)))
+ instrs.append((7, 5, 2, 2, 0, (1, 0)))
+ instrs.append((1, 7, 5, 0, 0, (0, 1)))
+ instrs.append((1, 6, 1, 2, 0, (1, 0)))
+ instrs.append((1, 6, 7, 3, 0, (0, 0)))
+ instrs.append((6, 7, 7, 0, 0, (0, 0)))
# issue instruction(s), wait for issue to be free before proceeding
for i, instr in enumerate(instrs):
src1, src2, dest, op, opi, imm, (br_ok, br_fail) = instr
- print ("instr %d: (%d, %d, %d, %d, %d, %d)" % \
- (i, src1, src2, dest, op, opi, imm))
+ print("instr %d: (%d, %d, %d, %d, %d, %d)" %
+ (i, src1, src2, dest, op, opi, imm))
alusim.op(op, opi, imm, src1, src2, dest)
yield from instr_q(dut, op, opi, imm, src1, src2, dest,
br_ok, br_fail)
f.write(vl)
run_simulation(dut, scoreboard_sim(dut, alusim),
- vcd_name='test_scoreboard6600.vcd')
+ vcd_name='test_scoreboard6600.vcd')
- #run_simulation(dut, scoreboard_branch_sim(dut, alusim),
+ # run_simulation(dut, scoreboard_branch_sim(dut, alusim),
# vcd_name='test_scoreboard6600.vcd')
yield dut.addrs_i[2].eq(0x010)
yield dut.addr_en_i.eq(0x3)
yield
- yield dut.addr_we_i.eq(0x3)
+ # FIXME: addr_we_i is commented out
+ # yield dut.addr_we_i.eq(0x3)
yield
yield dut.go_ld_i.eq(0x1)
yield
f.write(vl)
run_simulation(dut, mem_sim(dut),
- vcd_name='test_mem_fus.vcd')
+ vcd_name='test_mem_fus.vcd')
if __name__ == '__main__':
from nmigen.cli import verilog, rtlil
from nmigen import Module, Const, Signal, Array, Cat, Elaboratable
-from regfile.regfile import RegFileArray, treereduce
+from soc.regfile.regfile import RegFileArray, treereduce
from soc.scoreboard.ldst_matrix import LDSTDepMatrix
from soc.scoreboard.fu_mem_matrix import FUMemDepMatrix
from soc.scoreboard.global_pending import GlobalPending
from soc.scoreboard.issue_unit import IssueUnitGroup, IssueUnitArray, RegDecode
from soc.scoreboard.shadow import ShadowMatrix, BranchSpeculationRecord
+
from nmutil.latch import SRLatch
from nmutil.nmoperator import eq
from copy import deepcopy
from math import log
+# FIXME: fixed up imports
+from ..experiment.score6600 import IssueToScoreboard, RegSim, instr_q, wait_for_busy_clear, wait_for_issue, CompUnitALUs, CompUnitBR
+
class Memory(Elaboratable):
def __init__(self, regwid, addrw):
self.ddepth = regwid/8
- depth = (1<<addrw) / self.ddepth
- self.adr = Signal(addrw)
+ depth = (1 << addrw) / self.ddepth
+ self.adr = Signal(addrw)
self.dat_r = Signal(regwid)
self.dat_w = Signal(regwid)
- self.we = Signal()
- self.mem = Memory(width=regwid, depth=depth, init=range(0, depth))
+ self.we = Signal()
+ self.mem = Memory(width=regwid, depth=depth, init=range(0, depth))
def elaborate(self, platform):
m = Module()
m.submodules.rdport = rdport = self.mem.read_port()
m.submodules.wrport = wrport = self.mem.write_port()
m.d.comb += [
- rdport.addr.eq(self.adr[self.ddepth:]), # ignore low bits
+ rdport.addr.eq(self.adr[self.ddepth:]), # ignore low bits
self.dat_r.eq(rdport.data),
wrport.addr.eq(self.adr),
wrport.data.eq(self.dat_w),
def __init__(self, regwid, addrw):
self.regwid = regwid
self.ddepth = regwid//8
- depth = (1<<addrw) // self.ddepth
+ depth = (1 << addrw) // self.ddepth
self.mem = list(range(0, depth))
def ld(self, addr):
- return self.mem[addr>>self.ddepth]
+ return self.mem[addr >> self.ddepth]
def st(self, addr, data):
- self.mem[addr>>self.ddepth] = data & ((1<<self.regwid)-1)
+ self.mem[addr >> self.ddepth] = data & ((1 << self.regwid)-1)
class MemFunctionUnits(Elaboratable):
def __init__(self, n_int_alus):
self.n_int_alus = n_int_alus
- self.ld_i = Signal(n_int_alus, reset_less=True) # Dest R# in
- self.st_i = Signal(n_int_alus, reset_less=True) # oper1 R# in
+ self.ld_i = Signal(n_int_alus, reset_less=True) # Dest R# in
+ self.st_i = Signal(n_int_alus, reset_less=True) # oper1 R# in
- self.load_hit_i = Signal(n_int_alus, reset_less=True) # Load Hit
- self.stwd_hit_i = Signal(n_int_alus, reset_less=True) # Store Hit
+ self.load_hit_i = Signal(n_int_alus, reset_less=True) # Load Hit
+ self.stwd_hit_i = Signal(n_int_alus, reset_less=True) # Store Hit
#self.g_int_st_pend_o = Signal(n_int_alus, reset_less=True)
#self.g_int_ld_pend_o = Signal(n_int_alus, reset_less=True)
- #self.ld_rsel_o = Signal(n_int_alus, reset_less=True) # dest reg (bot)
- #self.st_rsel_o = Signal(n_int_alus, reset_less=True) # src1 reg (bot)
+ # self.ld_rsel_o = Signal(n_int_alus, reset_less=True) # dest reg (bot)
+ # self.st_rsel_o = Signal(n_int_alus, reset_less=True) # src1 reg (bot)
- self.req_rel_i = Signal(n_int_alus, reset_less = True)
+ self.req_rel_i = Signal(n_int_alus, reset_less=True)
self.loadable_o = Signal(n_int_alus, reset_less=True)
self.storable_o = Signal(n_int_alus, reset_less=True)
#comb += ldstdeps.st_pend_i.eq(fumemdeps.st_pend_o)
#comb += ldstdeps.ld_pend_i.eq(fumemdeps.ld_pend_o)
- #self.ld_pend_o = fumemdeps.ld_pend_o # also output for use in WaWGrid
+ # self.ld_pend_o = fumemdeps.ld_pend_o # also output for use in WaWGrid
comb += ldstdeps.ld_pend_i.eq(self.ld_i)
comb += ldstdeps.st_pend_i.eq(self.st_i)
def __iter__(self):
yield self.ld_i
yield self.st_i
- #yield self.g_int_st_pend_o
- #yield self.g_int_ld_pend_o
- #yield self.ld_rsel_o
- #yield self.st_rsel_o
+ # yield self.g_int_st_pend_o
+ # yield self.g_int_ld_pend_o
+ # yield self.ld_rsel_o
+ # yield self.st_rsel_o
yield self.req_rel_i
yield self.loadable_o
yield self.storable_o
self.br_imm_i = Signal(rwid, reset_less=True)
# inputs
- self.int_dest_i = Signal(max=n_regs, reset_less=True) # Dest R# in
- self.int_src1_i = Signal(max=n_regs, reset_less=True) # oper1 R# in
- self.int_src2_i = Signal(max=n_regs, reset_less=True) # oper2 R# in
- self.reg_enable_i = Signal(reset_less=True) # enable reg decode
+ self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
+ self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
+ self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
+ self.reg_enable_i = Signal(reset_less=True) # enable reg decode
# outputs
- self.issue_o = Signal(reset_less=True) # instruction was accepted
- self.busy_o = Signal(reset_less=True) # at least one CU is busy
+ self.issue_o = Signal(reset_less=True) # instruction was accepted
+ self.busy_o = Signal(reset_less=True) # at least one CU is busy
# for branch speculation experiment. branch_direction = 0 if
# the branch hasn't been met yet. 1 indicates "success", 2 is "fail"
cua = CompUnitALUs(self.rwid, 3)
cub = CompUnitBR(self.rwid, 3)
m.submodules.cu = cu = CompUnitsBase(self.rwid, [cua, cub])
- bgt = cub.bgt # get at the branch computation unit
+ bgt = cub.bgt # get at the branch computation unit
br1 = cub.br1
# Int FUs
# Count of number of FUs
n_intfus = n_int_alus
- n_fp_fus = 0 # for now
+ n_fp_fus = 0 # for now
# Integer Priority Picker 1: Adder + Subtractor
- intpick1 = GroupPicker(n_intfus) # picks between add, sub, mul and shf
+ intpick1 = GroupPicker(n_intfus) # picks between add, sub, mul and shf
m.submodules.intpick1 = intpick1
# INT/FP Issue Unit
# allow/cancel can be issued as appropriate.
m.submodules.specrec = bspec = BranchSpeculationRecord(n_intfus)
- #---------
+ # ---------
# ok start wiring things together...
# "now hear de word of de looord... dem bones dem bones dem dryy bones"
# https://www.youtube.com/watch?v=pYb8Wm6-QfA
- #---------
+ # ---------
- #---------
+ # ---------
# Issue Unit is where it starts. set up some in/outs for this module
- #---------
- comb += [ regdecode.dest_i.eq(self.int_dest_i),
- regdecode.src1_i.eq(self.int_src1_i),
- regdecode.src2_i.eq(self.int_src2_i),
- regdecode.enable_i.eq(self.reg_enable_i),
- self.issue_o.eq(issueunit.issue_o)
- ]
+ # ---------
+ comb += [regdecode.dest_i.eq(self.int_dest_i),
+ regdecode.src1_i.eq(self.int_src1_i),
+ regdecode.src2_i.eq(self.int_src2_i),
+ regdecode.enable_i.eq(self.reg_enable_i),
+ self.issue_o.eq(issueunit.issue_o)
+ ]
# take these to outside (issue needs them)
comb += cua.oper_i.eq(self.alu_oper_i)
comb += issueunit.busy_i.eq(cu.busy_o)
comb += self.busy_o.eq(cu.busy_o.bool())
- #---------
+ # ---------
# merge shadow matrices outputs
- #---------
+ # ---------
# these are explained in ShadowMatrix docstring, and are to be
# connected to the FUReg and FUFU Matrices, to get them to reset
comb += anydie.eq(shadows.go_die_o | bshadow.go_die_o)
comb += shreset.eq(bspec.match_g_o | bspec.match_f_o)
- #---------
+ # ---------
# connect fu-fu matrix
- #---------
+ # ---------
# Group Picker... done manually for now.
go_rd_o = intpick1.go_rd_o
go_wr_i = intfus.go_wr_i
go_die_i = intfus.go_die_i
# NOTE: connect to the shadowed versions so that they can "die" (reset)
- comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
- comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
- comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
+ comb += go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) # rd
+ comb += go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) # wr
+ comb += go_die_i[0:n_intfus].eq(anydie[0:n_intfus]) # die
# Connect Picker
- #---------
+ # ---------
comb += intpick1.rd_rel_i[0:n_intfus].eq(cu.rd_rel_o[0:n_intfus])
comb += intpick1.req_rel_i[0:n_intfus].eq(cu.req_rel_o[0:n_intfus])
int_rd_o = intfus.readable_o
comb += intpick1.readable_i[0:n_intfus].eq(int_rd_o[0:n_intfus])
comb += intpick1.writable_i[0:n_intfus].eq(int_wr_o[0:n_intfus])
- #---------
+ # ---------
# Shadow Matrix
- #---------
+ # ---------
comb += shadows.issue_i.eq(fn_issue_o)
#comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
comb += shadows.reset_i[0:n_intfus].eq(bshadow.go_die_o[0:n_intfus])
- #---------
+ # ---------
# NOTE; this setup is for the instruction order preservation...
# connect shadows / go_dies to Computation Units
for i in range(n_intfus):
comb += shadows.shadow_i[i][0:n_intfus].eq(prev_shadow)
- #---------
+ # ---------
# ... and this is for branch speculation. it uses the extra bit
# tacked onto the ShadowMatrix (hence shadow_wid=n_intfus+1)
# only needs to set shadow_i, s_fail_i and s_good_i
with m.If(bactive & (self.branch_succ_i | self.branch_fail_i)):
comb += bshadow.issue_i.eq(fn_issue_o)
for i in range(n_intfus):
- with m.If(fn_issue_o & (Const(1<<i))):
+ with m.If(fn_issue_o & (Const(1 << i))):
comb += bshadow.shadow_i[i][0].eq(1)
# finally, we need an indicator to the test infrastructure as to
# ... or it didn't
comb += bshadow.s_fail_i[i][0].eq(bspec.match_f_o[i])
- #---------
+ # ---------
# Connect Register File(s)
- #---------
+ # ---------
comb += int_dest.wen.eq(intfus.dest_rsel_o)
comb += int_src1.ren.eq(intfus.src1_rsel_o)
comb += int_src2.ren.eq(intfus.src2_rsel_o)
return list(self)
-
-
def int_instr(dut, op, imm, src1, src2, dest, branch_success, branch_fail):
yield from disable_issue(dut)
yield dut.int_dest_i.eq(dest)
yield dut.int_src1_i.eq(src1)
yield dut.int_src2_i.eq(src2)
- if (op & (0x3<<2)) != 0: # branch
+ if (op & (0x3 << 2)) != 0: # branch
yield dut.brissue.insn_i.eq(1)
yield dut.br_oper_i.eq(Const(op & 0x3, 2))
yield dut.br_imm_i.eq(imm)
reg = yield dut.intregs.regs[rnum].reg
rs.append("%x" % reg)
rnums = map(str, rnums)
- print ("reg %s: %s" % (','.join(rnums), ','.join(rs)))
+ print("reg %s: %s" % (','.join(rnums), ','.join(rs)))
def create_random_ops(dut, n_ops, shadowing=False, max_opnums=3):
for i in range(n_ops):
src1 = randint(1, dut.n_regs-1)
src2 = randint(1, dut.n_regs-1)
- imm = randint(1, (1<<dut.rwid)-1)
+ imm = randint(1, (1 << dut.rwid)-1)
dest = randint(1, dut.n_regs-1)
op = randint(0, max_opnums)
- opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
+ opi = 0 if randint(0, 2) else 1 # set true if random is nonzero
if shadowing:
insts.append((src1, src2, dest, op, opi, imm, (0, 0)))
return insts
-
def scoreboard_sim(dut, alusim):
seed(0)
# set random values in the registers
for i in range(1, dut.n_regs):
- val = randint(0, (1<<alusim.rwidth)-1)
+ val = randint(0, (1 << alusim.rwidth)-1)
#val = 31+i*3
#val = i
yield dut.intregs.regs[i].reg.eq(val)
instrs = create_random_ops(dut, 15, True, 4)
if False:
- instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
+ instrs.append((1, 2, 2, 1, 1, 20, (0, 0)))
if False:
- instrs.append( (7, 3, 2, 4, (0, 0)) )
- instrs.append( (7, 6, 6, 2, (0, 0)) )
- instrs.append( (1, 7, 2, 2, (0, 0)) )
+ instrs.append((7, 3, 2, 4, (0, 0)))
+ instrs.append((7, 6, 6, 2, (0, 0)))
+ instrs.append((1, 7, 2, 2, (0, 0)))
if False:
instrs.append((2, 3, 3, 0, 0, 0, (0, 0)))
instrs.append((3, 5, 5, 0, 0, 0, (0, 0)))
if False:
- instrs.append( (3, 3, 4, 0, 0, 13979, (0, 0)))
- instrs.append( (6, 4, 1, 2, 0, 40976, (0, 0)))
- instrs.append( (1, 4, 7, 4, 1, 23652, (0, 0)))
+ instrs.append((3, 3, 4, 0, 0, 13979, (0, 0)))
+ instrs.append((6, 4, 1, 2, 0, 40976, (0, 0)))
+ instrs.append((1, 4, 7, 4, 1, 23652, (0, 0)))
if False:
instrs.append((5, 6, 2, 1))
if False:
# Write-after-Write Hazard
- instrs.append( (3, 6, 7, 2) )
- instrs.append( (4, 4, 7, 1) )
+ instrs.append((3, 6, 7, 2))
+ instrs.append((4, 4, 7, 1))
if False:
# self-read/write-after-write followed by Read-after-Write
if False:
# very weird failure
- instrs.append( (5, 2, 5, 2) )
- instrs.append( (2, 6, 3, 0) )
- instrs.append( (4, 2, 2, 1) )
+ instrs.append((5, 2, 5, 2))
+ instrs.append((2, 6, 3, 0))
+ instrs.append((4, 2, 2, 1))
if False:
v1 = 4
instrs.append((4, 2, 1, 2, (1, 0)))
if False:
- instrs.append( (4, 3, 5, 1, 0, (0, 0)) )
- instrs.append( (5, 2, 3, 1, 0, (0, 0)) )
- instrs.append( (7, 1, 5, 2, 0, (0, 0)) )
- instrs.append( (5, 6, 6, 4, 0, (0, 0)) )
- instrs.append( (7, 5, 2, 2, 0, (1, 0)) )
- instrs.append( (1, 7, 5, 0, 0, (0, 1)) )
- instrs.append( (1, 6, 1, 2, 0, (1, 0)) )
- instrs.append( (1, 6, 7, 3, 0, (0, 0)) )
- instrs.append( (6, 7, 7, 0, 0, (0, 0)) )
+ instrs.append((4, 3, 5, 1, 0, (0, 0)))
+ instrs.append((5, 2, 3, 1, 0, (0, 0)))
+ instrs.append((7, 1, 5, 2, 0, (0, 0)))
+ instrs.append((5, 6, 6, 4, 0, (0, 0)))
+ instrs.append((7, 5, 2, 2, 0, (1, 0)))
+ instrs.append((1, 7, 5, 0, 0, (0, 1)))
+ instrs.append((1, 6, 1, 2, 0, (1, 0)))
+ instrs.append((1, 6, 7, 3, 0, (0, 0)))
+ instrs.append((6, 7, 7, 0, 0, (0, 0)))
# issue instruction(s), wait for issue to be free before proceeding
for i, instr in enumerate(instrs):
src1, src2, dest, op, opi, imm, (br_ok, br_fail) = instr
- print ("instr %d: (%d, %d, %d, %d, %d, %d)" % \
- (i, src1, src2, dest, op, opi, imm))
+ print("instr %d: (%d, %d, %d, %d, %d, %d)" %
+ (i, src1, src2, dest, op, opi, imm))
alusim.op(op, opi, imm, src1, src2, dest)
yield from instr_q(dut, op, opi, imm, src1, src2, dest,
br_ok, br_fail)
f.write(vl)
run_simulation(dut, scoreboard_sim(dut, alusim),
- vcd_name='test_scoreboard6600.vcd')
+ vcd_name='test_scoreboard6600.vcd')
- #run_simulation(dut, scoreboard_branch_sim(dut, alusim),
+ # run_simulation(dut, scoreboard_branch_sim(dut, alusim),
# vcd_name='test_scoreboard6600.vcd')
yield dut.ld_i.eq(0x1)
yield dut.fn_issue_i.eq(0x1)
yield
- #yield dut.ld_i.eq(0x0)
+ # yield dut.ld_i.eq(0x0)
yield dut.st_i.eq(0x2)
yield dut.fn_issue_i.eq(0x2)
yield
- #yield dut.st_i.eq(0x0)
+ # yield dut.st_i.eq(0x0)
yield dut.fn_issue_i.eq(0x0)
yield
f.write(vl)
run_simulation(dut, mem_sim(dut),
- vcd_name='test_mem_fus.vcd')
+ vcd_name='test_mem_fus.vcd')
if __name__ == '__main__':
"add 3, 1, 2",
"and 4, 1, 2"]
with Program(lst) as program:
- self.run_test_program(program, [1, 2, 3, 4])
+ self.run_tst_program(program, [1, 2, 3, 4])
def test_ldst(self):
lst = ["addi 1, 0, 0x1234",
"stw 1, 0(2)",
"lwz 3, 0(2)"]
with Program(lst) as program:
- self.run_test_program(program, [1, 2, 3])
+ self.run_tst_program(program, [1, 2, 3])
def test_ldst_extended(self):
lst = ["addi 1, 0, 0x1234",
"stw 1, 0x40(2)",
"lwzx 3, 4, 2"]
with Program(lst) as program:
- self.run_test_program(program, [1, 2, 3])
+ self.run_tst_program(program, [1, 2, 3])
def test_ldst_widths(self):
lst = [" lis 1, 0xdead",
"stb 5, 5(2)",
"ld 5, 0(2)"]
with Program(lst) as program:
- self.run_test_program(program, [1, 2, 3, 4, 5])
+ self.run_tst_program(program, [1, 2, 3, 4, 5])
def test_sub(self):
lst = ["addi 1, 0, 0x1234",
"subfic 4, 1, 0x1337",
"neg 5, 1"]
with Program(lst) as program:
- self.run_test_program(program, [1, 2, 3, 4, 5])
+ self.run_tst_program(program, [1, 2, 3, 4, 5])
- def run_test_program(self, prog, reglist):
+ def run_tst_program(self, prog, reglist):
simulator = InternalOpSimulator()
self.run_tst(prog, simulator)
prog.reset()