From 0554b11cfc7dbbfa2022ca304b193b91b6c39c04 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 6 Oct 2020 14:03:53 +0100 Subject: [PATCH] add LDSTException to PortInterface --- src/soc/experiment/compldst_multi.py | 11 ++++++----- src/soc/experiment/pi2ls.py | 2 +- src/soc/experiment/pimem.py | 24 ++++++++++++++++++------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/soc/experiment/compldst_multi.py b/src/soc/experiment/compldst_multi.py index 9f64b4fa..8e9f4ec3 100644 --- a/src/soc/experiment/compldst_multi.py +++ b/src/soc/experiment/compldst_multi.py @@ -89,6 +89,7 @@ from nmutil.extend import exts from soc.experiment.compalu_multi import go_record, CompUnitRecord from soc.experiment.l0_cache import PortInterface +from soc.experiment.pimem import LDSTException from soc.fu.regspec import RegSpecAPI from soc.decoder.power_enums import MicrOp, Function, LDSTMode @@ -104,7 +105,7 @@ class LDSTCompUnitRecord(CompUnitRecord): self.ad = go_record(1, name="cu_ad") # address go in, req out self.st = go_record(1, name="cu_st") # store go in, req out - self.addr_exc_o = Signal(reset_less=True) # address exception + self.exception_o = LDSTException("exc") self.ld_o = Signal(reset_less=True) # operation is a LD self.st_o = Signal(reset_less=True) # operation is a ST @@ -132,9 +133,9 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): -------------- * :data_o: Dest out (LD) - managed by wr[0] go/req * :addr_o: Address out (LD or ST) - managed by wr[1] go/req - * :addr_exc_o: Address/Data Exception occurred. LD/ST must terminate + * :exception_o: Address/Data Exception occurred. LD/ST must terminate - TODO: make addr_exc_o a data-type rather than a single-bit signal + TODO: make exception_o a data-type rather than a single-bit signal (see bug #302) Control Signals (In) @@ -227,7 +228,7 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): self.data_o = Data(self.data_wid, name="o") # Dest1 out: RT self.addr_o = Data(self.data_wid, name="ea") # Addr out: Update => RA - self.addr_exc_o = cu.addr_exc_o + self.exception_o = cu.exception_o self.done_o = cu.done_o self.busy_o = cu.busy_o @@ -491,7 +492,7 @@ class LDSTCompUnit(RegSpecAPI, Elaboratable): # address: use sync to avoid long latency sync += pi.addr.data.eq(addr_r) # EA from adder sync += pi.addr.ok.eq(alu_ok & lsd_l.q) # "do address stuff" (once) - comb += self.addr_exc_o.eq(pi.addr_exc_o) # exception occurred + comb += self.exception_o.eq(pi.exception_o) # exception occurred comb += addr_ok.eq(self.pi.addr_ok_o) # no exc, address fine # byte-reverse on LD diff --git a/src/soc/experiment/pi2ls.py b/src/soc/experiment/pi2ls.py index 3964122b..abba37e1 100644 --- a/src/soc/experiment/pi2ls.py +++ b/src/soc/experiment/pi2ls.py @@ -14,7 +14,7 @@ addr.ok/1 probably x_valid_i & ~x_stall_i addr_ok_o/1 no equivalent. *might* work using x_stall_i - addr_exc_o/2(?) m_load_err_o and m_store_err_o + exception_o/2(?) m_load_err_o and m_store_err_o ld.data/64 m_ld_data_o ld.ok/1 probably implicit, when x_busy drops low diff --git a/src/soc/experiment/pimem.py b/src/soc/experiment/pimem.py index 89ba7714..dc846c12 100644 --- a/src/soc/experiment/pimem.py +++ b/src/soc/experiment/pimem.py @@ -33,6 +33,18 @@ from soc.experiment.testmem import TestMemory import unittest +class LDSTException(RecordObject): + def __init__(self, name=None): + RecordObject.__init__(self, name=name) + self.happened = Signal() + self.alignment = Signal() + self.instr_fault = Signal() + self.invalid = Signal() + self.badtree = Signal() + self.perm_error = Signal() + self.rc_error = Signal() + self.segment_fault = Signal() + class PortInterface(RecordObject): """PortInterface @@ -59,13 +71,13 @@ class PortInterface(RecordObject): for the L0 Cache/Buffer to have an additional address latch (because the LDSTCompUnit already has it) - * addr_ok_o (or addr_exc_o) must be waited for. these will + * addr_ok_o (or exception.happened) must be waited for. these will be asserted *only* for one cycle and one cycle only. - * addr_exc_o will be asserted if there is no chance that the + * exception.happened will be asserted if there is no chance that the memory request may be fulfilled. - busy_o is deasserted on the same cycle as addr_exc_o is asserted. + busy_o is deasserted on the same cycle as exception.happened is asserted. * conversely: addr_ok_o must *ONLY* be asserted if there is a HUNDRED PERCENT guarantee that the memory request will be @@ -107,7 +119,7 @@ class PortInterface(RecordObject): self.addr = Data(addrwid, "addr_i") # addr/addr-ok # addr is valid (TLB, L1 etc.) self.addr_ok_o = Signal(reset_less=True) - self.addr_exc_o = Signal(reset_less=True) # TODO, "type" of exception + self.exception_o = LDSTException("exc") # LD/ST self.ld = Data(regwid, "ld_data_o") # ok to be set by L0 Cache/Buf @@ -131,7 +143,7 @@ class PortInterface(RecordObject): inport.ld.eq(self.ld), inport.busy_o.eq(self.busy_o), inport.addr_ok_o.eq(self.addr_ok_o), - inport.addr_exc_o.eq(self.addr_exc_o), + inport.exception_o.eq(self.exception_o), ] @@ -280,7 +292,7 @@ class PortInterfaceBase(Elaboratable): comb += st_done.r.eq(1) # store done reset # monitor for an exception or the completion of LD. - with m.If(self.pi.addr_exc_o): + with m.If(self.pi.exception_o.happened): comb += busy_l.r.eq(1) # however ST needs one cycle before busy is reset -- 2.30.2