Reduce code duplication in Minerva verification script

This commit is contained in:
Donald Sebastian Leung 2020-08-21 11:43:20 +08:00
parent de3ff25da1
commit d7d4f8b0ad
11 changed files with 161 additions and 1764 deletions

View File

@ -15,6 +15,7 @@ class CausalCheck(Elaboratable):
self.rvfi_order = Signal(64)
self.rvfi_rs1_addr = Signal(5)
self.rvfi_rs2_addr = Signal(5)
def ports(self):
input_ports = [
self.reset,
@ -26,6 +27,7 @@ class CausalCheck(Elaboratable):
self.rvfi_rs2_addr
]
return input_ports
def elaborate(self, platform):
m = Module()

View File

@ -6,13 +6,9 @@ Instruction Check
"""
class InsnCheck(Elaboratable):
def __init__(self, RISCV_FORMAL_ILEN, RISCV_FORMAL_XLEN, RISCV_FORMAL_CSR_MISA, RISCV_FORMAL_COMPRESSED, RISCV_FORMAL_ALIGNED_MEM, insn_model, rvformal_addr_valid):
# Core-specific constants
self.RISCV_FORMAL_ILEN = RISCV_FORMAL_ILEN
self.RISCV_FORMAL_XLEN = RISCV_FORMAL_XLEN
self.RISCV_FORMAL_CSR_MISA = RISCV_FORMAL_CSR_MISA
self.RISCV_FORMAL_COMPRESSED = RISCV_FORMAL_COMPRESSED
self.RISCV_FORMAL_ALIGNED_MEM = RISCV_FORMAL_ALIGNED_MEM
def __init__(self, params, insn_model, rvformal_addr_valid):
# Core-specific parameters
self.params = params
# Instruction under test
self.insn_model = insn_model
@ -26,7 +22,7 @@ class InsnCheck(Elaboratable):
self.check = Signal(1)
self.rvfi_valid = Signal(1)
self.rvfi_order = Signal(64)
self.rvfi_insn = Signal(self.RISCV_FORMAL_ILEN)
self.rvfi_insn = Signal(self.params.ilen)
self.rvfi_trap = Signal(1)
self.rvfi_halt = Signal(1)
self.rvfi_intr = Signal(1)
@ -34,22 +30,23 @@ class InsnCheck(Elaboratable):
self.rvfi_ixl = Signal(2)
self.rvfi_rs1_addr = Signal(5)
self.rvfi_rs2_addr = Signal(5)
self.rvfi_rs1_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rs2_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rs1_rdata = Signal(self.params.xlen)
self.rvfi_rs2_rdata = Signal(self.params.xlen)
self.rvfi_rd_addr = Signal(5)
self.rvfi_rd_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_mem_addr = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_mem_rmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
self.rvfi_mem_wmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
self.rvfi_mem_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_mem_wdata = Signal(self.RISCV_FORMAL_XLEN)
if self.RISCV_FORMAL_CSR_MISA:
self.rvfi_csr_misa_rmask = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_csr_misa_wmask = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_csr_misa_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_csr_misa_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rd_wdata = Signal(self.params.xlen)
self.rvfi_pc_rdata = Signal(self.params.xlen)
self.rvfi_pc_wdata = Signal(self.params.xlen)
self.rvfi_mem_addr = Signal(self.params.xlen)
self.rvfi_mem_rmask = Signal(int(self.params.xlen // 8))
self.rvfi_mem_wmask = Signal(int(self.params.xlen // 8))
self.rvfi_mem_rdata = Signal(self.params.xlen)
self.rvfi_mem_wdata = Signal(self.params.xlen)
if self.params.csr_misa:
self.rvfi_csr_misa_rmask = Signal(self.params.xlen)
self.rvfi_csr_misa_wmask = Signal(self.params.xlen)
self.rvfi_csr_misa_rdata = Signal(self.params.xlen)
self.rvfi_csr_misa_wdata = Signal(self.params.xlen)
def ports(self):
input_ports = [
self.reset,
@ -76,7 +73,7 @@ class InsnCheck(Elaboratable):
self.rvfi_mem_rdata,
self.rvfi_mem_wdata
]
if self.RISCV_FORMAL_CSR_MISA:
if self.params.csr_misa:
input_ports.extend([
self.rvfi_csr_misa_rmask,
self.rvfi_csr_misa_wmask,
@ -84,78 +81,54 @@ class InsnCheck(Elaboratable):
self.rvfi_csr_misa_wdata
])
return input_ports
def elaborate(self, platform):
m = Module()
valid = Signal(1)
m.d.comb += valid.eq((~self.reset) & self.rvfi_valid)
insn = Signal(self.RISCV_FORMAL_ILEN)
m.d.comb += insn.eq(self.rvfi_insn)
trap = Signal(1)
m.d.comb += trap.eq(self.rvfi_trap)
halt = Signal(1)
m.d.comb += halt.eq(self.rvfi_halt)
intr = Signal(1)
m.d.comb += intr.eq(self.rvfi_intr)
rs1_addr = Signal(5)
m.d.comb += rs1_addr.eq(self.rvfi_rs1_addr)
rs2_addr = Signal(5)
m.d.comb += rs2_addr.eq(self.rvfi_rs2_addr)
rs1_rdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += rs1_rdata.eq(self.rvfi_rs1_rdata)
rs2_rdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += rs2_rdata.eq(self.rvfi_rs2_rdata)
rd_addr = Signal(5)
m.d.comb += rd_addr.eq(self.rvfi_rd_addr)
rd_wdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += rd_wdata.eq(self.rvfi_rd_wdata)
pc_rdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += pc_rdata.eq(self.rvfi_pc_rdata)
pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += pc_wdata.eq(self.rvfi_pc_wdata)
insn = self.rvfi_insn
trap = self.rvfi_trap
halt = self.rvfi_halt
intr = self.rvfi_intr
rs1_addr = self.rvfi_rs1_addr
rs2_addr = self.rvfi_rs2_addr
rs1_rdata = self.rvfi_rs1_rdata
rs2_rdata = self.rvfi_rs2_rdata
rd_addr = self.rvfi_rd_addr
rd_wdata = self.rvfi_rd_wdata
pc_rdata = self.rvfi_pc_rdata
pc_wdata = self.rvfi_pc_wdata
mem_addr = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += mem_addr.eq(self.rvfi_mem_addr)
mem_rmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
m.d.comb += mem_rmask.eq(self.rvfi_mem_rmask)
mem_wmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
m.d.comb += mem_wmask.eq(self.rvfi_mem_wmask)
mem_rdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += mem_rdata.eq(self.rvfi_mem_rdata)
mem_wdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += mem_wdata.eq(self.rvfi_mem_wdata)
mem_addr = self.rvfi_mem_addr
mem_rmask = self.rvfi_mem_rmask
mem_wmask = self.rvfi_mem_wmask
mem_rdata = self.rvfi_mem_rdata
mem_wdata = self.rvfi_mem_wdata
if self.RISCV_FORMAL_CSR_MISA:
csr_misa_rdata = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += csr_misa_rdata.eq(self.rvfi_csr_misa_rdata)
csr_misa_rmask = Signal(self.RISCV_FORMAL_XLEN)
m.d.comb += csr_misa_rmask.eq(self.rvfi_csr_misa_rmask)
spec_csr_misa_rmask = Signal(self.RISCV_FORMAL_XLEN)
if self.params.csr_misa:
csr_misa_rdata = self.rvfi_csr_misa_rdata
csr_misa_rmask = self.rvfi_csr_misa_rmask
spec_csr_misa_rmask = Signal(self.params.xlen)
spec_valid = Signal(1)
spec_trap = Signal(1)
spec_rs1_addr = Signal(5)
spec_rs2_addr = Signal(5)
spec_rd_addr = Signal(5)
spec_rd_wdata = Signal(self.RISCV_FORMAL_XLEN)
spec_pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
spec_mem_addr = Signal(self.RISCV_FORMAL_XLEN)
spec_mem_rmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
spec_mem_wmask = Signal(int(self.RISCV_FORMAL_XLEN // 8))
spec_mem_wdata = Signal(self.RISCV_FORMAL_XLEN)
spec_rd_wdata = Signal(self.params.xlen)
spec_pc_wdata = Signal(self.params.xlen)
spec_mem_addr = Signal(self.params.xlen)
spec_mem_rmask = Signal(int(self.params.xlen // 8))
spec_mem_wmask = Signal(int(self.params.xlen // 8))
spec_mem_wdata = Signal(self.params.xlen)
rs1_rdata_or_zero = Signal(self.RISCV_FORMAL_XLEN)
rs1_rdata_or_zero = Signal(self.params.xlen)
m.d.comb += rs1_rdata_or_zero.eq(Mux(spec_rs1_addr != 0, rs1_rdata, 0))
rs2_rdata_or_zero = Signal(self.RISCV_FORMAL_XLEN)
rs2_rdata_or_zero = Signal(self.params.xlen)
m.d.comb += rs2_rdata_or_zero.eq(Mux(spec_rs2_addr != 0, rs2_rdata, 0))
try:
m.submodules.insn_spec = insn_spec = self.insn_model(RISCV_FORMAL_ILEN=self.RISCV_FORMAL_ILEN, RISCV_FORMAL_XLEN=self.RISCV_FORMAL_XLEN, RISCV_FORMAL_CSR_MISA=self.RISCV_FORMAL_CSR_MISA)
except:
try:
m.submodules.insn_spec = insn_spec = self.insn_model(RISCV_FORMAL_ILEN=self.RISCV_FORMAL_ILEN, RISCV_FORMAL_XLEN=self.RISCV_FORMAL_XLEN, RISCV_FORMAL_CSR_MISA=self.RISCV_FORMAL_CSR_MISA, RISCV_FORMAL_COMPRESSED=self.RISCV_FORMAL_COMPRESSED)
except:
m.submodules.insn_spec = insn_spec = self.insn_model(RISCV_FORMAL_ILEN=self.RISCV_FORMAL_ILEN, RISCV_FORMAL_XLEN=self.RISCV_FORMAL_XLEN, RISCV_FORMAL_CSR_MISA=self.RISCV_FORMAL_CSR_MISA, RISCV_FORMAL_ALIGNED_MEM=self.RISCV_FORMAL_ALIGNED_MEM)
m.submodules.insn_spec = insn_spec = self.insn_model(self.params)
m.d.comb += insn_spec.rvfi_valid.eq(valid)
m.d.comb += insn_spec.rvfi_insn.eq(insn)
@ -164,7 +137,7 @@ class InsnCheck(Elaboratable):
m.d.comb += insn_spec.rvfi_rs2_rdata.eq(rs2_rdata_or_zero)
m.d.comb += insn_spec.rvfi_mem_rdata.eq(mem_rdata)
if self.RISCV_FORMAL_CSR_MISA:
if self.params.csr_misa:
m.d.comb += insn_spec.rvfi_csr_misa_rdata.eq(csr_misa_rdata)
m.d.comb += spec_csr_misa_rmask.eq(insn_spec.spec_csr_misa_rmask)
@ -208,7 +181,7 @@ class InsnCheck(Elaboratable):
m.d.comb += Assert(rd_wdata == 0)
m.d.comb += Assert(mem_wmask == 0)
with m.Else():
if self.RISCV_FORMAL_CSR_MISA:
if self.params.csr_misa:
m.d.comb += Assert((spec_csr_misa_rmask & csr_misa_rmask) == spec_csr_misa_rmask)
with m.If(rs1_addr == 0):
@ -231,7 +204,7 @@ class InsnCheck(Elaboratable):
with m.If(spec_mem_wmask | spec_mem_rmask):
m.d.comb += Assert(self.rvformal_addr_eq(spec_mem_addr, mem_addr))
for i in range(int(self.RISCV_FORMAL_XLEN // 8)):
for i in range(int(self.params.xlen // 8)):
with m.If(spec_mem_wmask[i]):
m.d.comb += Assert(mem_wmask[i])
m.d.comb += Assert(spec_mem_wdata[i*8:i*8+8] == mem_wdata[i*8:i*8+8])

View File

@ -6,9 +6,9 @@ PC Backward Check
"""
class PcBwdCheck(Elaboratable):
def __init__(self, RISCV_FORMAL_XLEN, rvformal_addr_valid):
# Core-specific constants
self.RISCV_FORMAL_XLEN = RISCV_FORMAL_XLEN
def __init__(self, params, rvformal_addr_valid):
# Core-specific parameters
self.params = params
# Address validity and equality
self.rvformal_addr_valid = rvformal_addr_valid
@ -19,8 +19,9 @@ class PcBwdCheck(Elaboratable):
self.check = Signal(1)
self.rvfi_valid = Signal(1)
self.rvfi_order = Signal(64)
self.rvfi_pc_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_rdata = Signal(self.params.xlen)
self.rvfi_pc_wdata = Signal(self.params.xlen)
def ports(self):
input_ports = [
self.reset,
@ -31,14 +32,15 @@ class PcBwdCheck(Elaboratable):
self.rvfi_pc_wdata
]
return input_ports
def elaborate(self, platform):
m = Module()
insn_order = AnyConst(64)
expect_pc = Signal(self.RISCV_FORMAL_XLEN)
expect_pc = Signal(self.params.xlen)
expect_pc_valid = Signal(1, reset=0)
pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
pc_wdata = Signal(self.params.xlen)
m.d.comb += pc_wdata.eq(self.rvfi_pc_wdata)
with m.If(self.reset):

View File

@ -6,9 +6,9 @@ PC Forward Check
"""
class PcFwdCheck(Elaboratable):
def __init__(self, RISCV_FORMAL_XLEN, rvformal_addr_valid):
# Core-specific constants
self.RISCV_FORMAL_XLEN = RISCV_FORMAL_XLEN
def __init__(self, params, rvformal_addr_valid):
# Core-specific parameters
self.params = params
# Address validity and equality
self.rvformal_addr_valid = rvformal_addr_valid
@ -19,8 +19,9 @@ class PcFwdCheck(Elaboratable):
self.check = Signal(1)
self.rvfi_valid = Signal(1)
self.rvfi_order = Signal(64)
self.rvfi_pc_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_pc_rdata = Signal(self.params.xlen)
self.rvfi_pc_wdata = Signal(self.params.xlen)
def ports(self):
input_ports = [
self.reset,
@ -31,14 +32,15 @@ class PcFwdCheck(Elaboratable):
self.rvfi_pc_wdata
]
return input_ports
def elaborate(self, platform):
m = Module()
insn_order = AnyConst(64)
expect_pc = Signal(self.RISCV_FORMAL_XLEN)
expect_pc = Signal(self.params.xlen)
expect_pc_valid = Signal(1, reset=0)
pc_rdata = Signal(self.RISCV_FORMAL_XLEN)
pc_rdata = Signal(self.params.xlen)
m.d.comb += pc_rdata.eq(self.rvfi_pc_rdata)
with m.If(self.reset):

View File

@ -6,9 +6,9 @@ Register Check
"""
class RegCheck(Elaboratable):
def __init__(self, RISCV_FORMAL_XLEN):
# Core-specific constants
self.RISCV_FORMAL_XLEN = RISCV_FORMAL_XLEN
def __init__(self, params):
# Core-specific parameters
self.params = params
# Input ports
self.reset = Signal(1)
@ -16,11 +16,12 @@ class RegCheck(Elaboratable):
self.rvfi_valid = Signal(1)
self.rvfi_order = Signal(64)
self.rvfi_rs1_addr = Signal(5)
self.rvfi_rs1_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rs1_rdata = Signal(self.params.xlen)
self.rvfi_rs2_addr = Signal(5)
self.rvfi_rs2_rdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rs2_rdata = Signal(self.params.xlen)
self.rvfi_rd_addr = Signal(5)
self.rvfi_rd_wdata = Signal(self.RISCV_FORMAL_XLEN)
self.rvfi_rd_wdata = Signal(self.params.xlen)
def ports(self):
input_ports = [
self.reset,
@ -35,12 +36,13 @@ class RegCheck(Elaboratable):
self.rvfi_rd_wdata
]
return input_ports
def elaborate(self, platform):
m = Module()
insn_order = AnyConst(64)
register_index = AnyConst(5)
register_shadow = Signal(self.RISCV_FORMAL_XLEN, reset=0)
register_shadow = Signal(self.params.xlen, reset=0)
register_written = Signal(1, reset=0)
with m.If(self.reset):

File diff suppressed because it is too large Load Diff

View File

@ -93,10 +93,10 @@ Below is a list of instructions currently supported by this port of the riscv-fo
The following core-specific parameters are currently supported:
| Constant | Description | Valid value(s) |
| Parameter | Description | Valid value(s) |
| --- | --- | --- |
| `RISCV_FORMAL_ILEN` | Max length of instruction retired by core | `32` |
| `RISCV_FORMAL_XLEN` | Width of integer registers | `32` |
| `RISCV_FORMAL_CSR_MISA` | Support for MISA CSRs enabled | `True`, `False` |
| `RISCV_FORMAL_COMPRESSED` | Support for compressed instructions | `True`, `False` |
| `RISCV_FORMAL_ALIGNED_MEM` | Require aligned memory accesses | `True`, `False` |
| `params.ilen` | Max length of instruction retired by core | `32` |
| `params.xlen` | Width of integer registers | `32` |
| `params.csr_misa` | Support for MISA CSRs enabled | `True`, `False` |
| `params.compressed` | Support for compressed instructions | `True`, `False` |
| `params.aligned_mem` | Require aligned memory accesses | `True`, `False` |

View File

@ -11,6 +11,6 @@ class InsnSll(InsnRV32IRType):
def elaborate(self, platform):
m = super().elaborate(platform)
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, self.rvfi_rs1_rdata << Mux(self.RISCV_FORMAL_XLEN == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]), 0))
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, self.rvfi_rs1_rdata << Mux(self.params.xlen == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]), 0))
return m

View File

@ -11,6 +11,6 @@ class InsnSra(InsnRV32IRType):
def elaborate(self, platform):
m = super().elaborate(platform)
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, (Value.as_signed(self.rvfi_rs1_rdata) >> Mux(self.RISCV_FORMAL_XLEN == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5])) | (-(Value.as_signed(self.rvfi_rs1_rdata) < 0) << (self.RISCV_FORMAL_XLEN - Mux(self.RISCV_FORMAL_XLEN == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]))), 0)) # https://stackoverflow.com/a/25207042
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, (Value.as_signed(self.rvfi_rs1_rdata) >> Mux(self.params.xlen == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5])) | (-(Value.as_signed(self.rvfi_rs1_rdata) < 0) << (self.params.xlen - Mux(self.params.xlen == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]))), 0)) # https://stackoverflow.com/a/25207042
return m

View File

@ -11,6 +11,6 @@ class InsnSrai(InsnRV32IITypeShift):
def elaborate(self, platform):
m = super().elaborate(platform)
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, (Value.as_signed(self.rvfi_rs1_rdata) >> self.insn_shamt) | (-(Value.as_signed(self.rvfi_rs1_rdata) < 0) << (self.RISCV_FORMAL_XLEN - self.insn_shamt)), 0))
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, (Value.as_signed(self.rvfi_rs1_rdata) >> self.insn_shamt) | (-(Value.as_signed(self.rvfi_rs1_rdata) < 0) << (self.params.xlen - self.insn_shamt)), 0))
return m

View File

@ -11,6 +11,6 @@ class InsnSrl(InsnRV32IRType):
def elaborate(self, platform):
m = super().elaborate(platform)
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, self.rvfi_rs1_rdata >> Mux(self.RISCV_FORMAL_XLEN == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]), 0))
m.d.comb += self.spec_rd_wdata.eq(Mux(self.spec_rd_addr, self.rvfi_rs1_rdata >> Mux(self.params.xlen == 64, self.rvfi_rs2_rdata[:6], self.rvfi_rs2_rdata[:5]), 0))
return m