| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -4,16 +4,75 @@ from amaranth.utils import log2_int
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from amaranth_soc import wishbone
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from power_fv.check.storage import DataStorageCheck, DataStorageTestbench, DataStorageModel
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from power_fv.check.storage import *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				from ..core import *
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				__all__ = [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    "InsnStorageCheck_Microwatt", "InsnStorageTestbench_Microwatt", "InsnStorageModel_Microwatt",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    "DataStorageCheck_Microwatt", "DataStorageTestbench_Microwatt", "DataStorageModel_Microwatt",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class InsnStorageCheck_Microwatt(InsnStorageCheck, name=("microwatt", "storage", "insn")):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self, *, depth, skip, core, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not isinstance(core, MicrowattCore):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            raise TypeError("Core must be an instance of MicrowattCore, not {!r}"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                            .format(core))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        super().__init__(depth=depth, skip=skip, core=core, **kwargs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def testbench(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return InsnStorageTestbench_Microwatt(self)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class InsnStorageTestbench_Microwatt(InsnStorageTestbench):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def storage(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return InsnStorageModel_Microwatt()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class InsnStorageModel_Microwatt(InsnStorageModel, Elaboratable):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.addr  = Signal(64)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.data  = Signal(32)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self._ibus = wishbone.Interface(addr_width=29, data_width=64, granularity=8,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                        features=("stall",))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def connect(self, dut):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assert isinstance(dut, MicrowattWrapper)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assert dut.wb_insn.addr_width  == self._ibus.addr_width
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assert dut.wb_insn.data_width  == self._ibus.data_width
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        assert dut.wb_insn.granularity == self._ibus.granularity
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return self._ibus.eq(dut.wb_insn)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def elaborate(self, platform):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        m = Module()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with m.If(self._ibus.cyc & self._ibus.stb):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            m.d.comb += Assume(self._ibus.stall == ~self._ibus.ack)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with m.If(self._ibus.ack):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            m.d.comb += [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(self._ibus.cyc & Past(self._ibus.cyc)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(self._ibus.stb & Past(self._ibus.stb)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(~Past(self._ibus.ack)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        m.d.comb += [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.addr.eq(Cat(AnyConst(32), Const(0, 32))),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.data.eq(AnyConst(32)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with m.If(self._ibus.cyc & self._ibus.stb & self._ibus.ack & ~ResetSignal("sync")):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            with m.If(self.addr == Cat(Const(0b000, 3), self._ibus.adr)):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                m.d.comb += Assume(self._ibus.dat_r[:32] == self.data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            with m.If(self.addr == Cat(Const(0b100, 3), self._ibus.adr)):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                m.d.comb += Assume(self._ibus.dat_r[32:] == self.data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return m
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class DataStorageCheck_Microwatt(DataStorageCheck, name=("microwatt", "storage", "data")):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self, *, depth, skip, core, **kwargs):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not isinstance(core, MicrowattCore):
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -53,15 +112,18 @@ class DataStorageModel_Microwatt(DataStorageModel, Elaboratable):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        m.d.comb += [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            dbus_read .eq(self._dbus.cyc & self._dbus.stb & self._dbus.ack),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            dbus_write.eq(self._dbus.cyc & self._dbus.stb & self._dbus.ack & self._dbus.we),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            Assume(self._dbus.ack.implies(Past(self._dbus.cyc) & self._dbus.cyc)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            Assume(self._dbus.ack.implies(Past(self._dbus.stb) & self._dbus.stb)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            Assume(self._dbus.ack.implies(~Past(self._dbus.ack))),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with m.If(self._dbus.cyc & self._dbus.stb):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            m.d.comb += Assume(self._dbus.stall == ~self._dbus.ack)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        with m.If(self._dbus.ack):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            m.d.comb += [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(self._dbus.cyc & Past(self._dbus.cyc)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(self._dbus.stb & Past(self._dbus.stb)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Assume(~Past(self._dbus.ack)),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        addr_lsb = log2_int(len(self._dbus.sel))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        addr_hit = Signal()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        value    = Signal(64)
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |