Skip to content

Commit

Permalink
Merge branch 'master' into tilk/faster-wishbone
Browse files Browse the repository at this point in the history
  • Loading branch information
tilk authored Nov 6, 2023
2 parents a4e9046 + bf83d82 commit 790365f
Show file tree
Hide file tree
Showing 11 changed files with 444 additions and 80 deletions.
86 changes: 36 additions & 50 deletions coreblocks/fu/fu_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,73 +44,59 @@ def elaborate(self, platform):


class DecoderManager:
"""
Class responsible for instruction management.
"""

"""
Type[IntFlag]
"""Class responsible for instruction management."""

Enumeration of instructions implemented in given functional unit.
"""
Fn: Type[IntFlag]

"""
Method providing list of valid instruction.
Returns
-------
return : Sequence[tuple]
List of implemented instructions, each following format:
(IntFlag, OpType, Funct3 (optional), Funct7 (optional))
"""
"""Enumeration of instructions implemented in given functional unit."""

def get_instructions(self) -> Sequence[tuple]:
raise NotImplementedError
"""Method providing list of valid instruction.
"""
Method returning op types from listed instructions.
Returns
-------
return : Sequence[tuple]
List of implemented instructions, each following format:
(IntFlag, OpType, Funct3 (optional), Funct7 (optional))
Returns
-------
return : set[OpType]
List of OpTypes.
"""
"""
raise NotImplementedError

def get_op_types(self) -> set[OpType]:
return {instr[1] for instr in self.get_instructions()}

"""
Method returning auto generated instruction decoder.
"""Method returning op types from listed instructions.
Parameters
----------
gen_params: GenParams
Generation parameters passed to a decoder contructor.
Returns
-------
return : set[OpType]
List of OpTypes.
"""
Returns
-------
return : set[OpType]
List of OpTypes.
"""
return {instr[1] for instr in self.get_instructions()}

def get_decoder(self, gen_params: GenParams) -> Decoder:
"""Method returning auto generated instruction decoder.
Parameters
----------
gen_params: GenParams
Generation parameters passed to a decoder contructor.
Returns
-------
return : set[OpType]
List of OpTypes.
"""
# check how many different op types are there
op_types = self.get_op_types()
multiple_op_types = len(op_types) > 1

# if multiple op types detected, request op_type check in decoder
return Decoder(gen_params, self.Fn, self.get_instructions(), check_optype=multiple_op_types)

"""
Method returning Signal Object for decoder, called function in FU blocks
Returns
-------
return : Value
Signal object.
"""

def get_function(self) -> Value:
"""Method returning Signal Object for decoder, called function in FU blocks
Returns
-------
return : Value
Signal object.
"""
return Signal(self.Fn)
12 changes: 8 additions & 4 deletions coreblocks/fu/zbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ class Zbs(Elaboratable):
First input.
in2: Signal(xlen), in
Second input.
Args:
----
gen_params: Core generation parameters.
"""

def __init__(self, gen_params: GenParams, function=ZbsFunction()):
"""
Parameters
----------
gen_params : GenParams
Core generation parameters.
function : ZbsFunction
Decoder manager to decode instruction.
"""
self.gen_params = gen_params

self.xlen = gen_params.isa.xlen
Expand Down
21 changes: 21 additions & 0 deletions coreblocks/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"OneHotSwitch",
"flatten_signals",
"align_to_power_of_two",
"align_down_to_power_of_two",
"bits_from_int",
"ModuleConnector",
"silence_mustuse",
Expand Down Expand Up @@ -377,6 +378,26 @@ def align_to_power_of_two(num: int, power: int) -> int:
return (num & ~mask) + 2**power


def align_down_to_power_of_two(num: int, power: int) -> int:
"""Rounds down a number to the given power of two.
Parameters
----------
num : int
The number to align.
power : int
The power of two to align to.
Returns
-------
int
The aligned number.
"""
mask = 2**power - 1

return num & ~mask


def bits_from_int(num: int, lower: int, length: int):
"""Returns [`lower`:`lower`+`length`) bits from integer `num`."""
return (num >> lower) & ((1 << (length)) - 1)
Expand Down
88 changes: 88 additions & 0 deletions scripts/run_signature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env python3

import asyncio
import argparse
import sys
import os
import subprocess
from typing import Literal

if __name__ == "__main__":
parent = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent)

import test.regression.signature # noqa: E402
from test.regression.pysim import PySimulation # noqa: E402


def run_with_cocotb(test_name: str, traces: bool, output: str) -> bool:
arglist = [
"make",
"-C",
parent + "/" if parent else "" + "test/regression/cocotb",
"-f",
"signature.Makefile",
"--no-print-directory",
]

if os.path.isfile(output):
os.remove(output)

arglist += [f"TESTNAME={test_name}"]
arglist += [f"OUTPUT={output}"]

if traces:
arglist += ["TRACES=1"]

subprocess.run(arglist)

return os.path.isfile(output) # completed successfully if signature file was created


def run_with_pysim(test_name: str, traces: bool, verbose: bool, output: str) -> bool:
traces_file = None
if traces:
traces_file = os.path.basename(test_name)
try:
asyncio.run(
test.regression.signature.run_test(PySimulation(verbose, traces_file=traces_file), test_name, output)
)
except RuntimeError as e:
print("RuntimeError:", e)
return False
return True


def run_test(test: str, backend: Literal["pysim", "cocotb"], traces: bool, verbose: bool, output: str) -> bool:
if backend == "cocotb":
return run_with_cocotb(test, traces, output)
elif backend == "pysim":
return run_with_pysim(test, traces, verbose, output)
return False


def main():
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--trace", action="store_true", help="Dump waveforms")
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
parser.add_argument("-b", "--backend", default="pysim", choices=["cocotb", "pysim"], help="Simulation backend")
parser.add_argument("-o", "--output", default=None, help="Selects output file to write test signature to")
parser.add_argument("path")

args = parser.parse_args()

output = args.output if args.output else args.path + ".signature"

success = run_test(args.path, args.backend, args.trace, args.verbose, output)
if not success:
print(f"{args.path}: Program execution failed")

if output is not None: # create empty file on failure for checker scripts
with open(output, "w"):
pass

sys.exit(1)


if __name__ == "__main__":
main()
40 changes: 40 additions & 0 deletions test/external/riscof/coreblocks/env/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
OUTPUT_ARCH( "riscv" )
ENTRY(rvtest_entry_point)

MEMORY
{
text (rxai!w) : ORIGIN = 0x00000000, LENGTH = 2M
data (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 1M
mmio (wa!rxi) : ORIGIN = 0x80000000, LENGTH = 1K
signature (wa!rxi) : ORIGIN = 0x81000000, LENGTH = 16K

}

PHDRS
{
text PT_LOAD;
data_init PT_LOAD;
data PT_NULL;
mmio PT_LOAD;
signature PT_LOAD;
}

SECTIONS
{
.text.init : { *(.text.init) } >text AT>text :text
. = ALIGN(0x1000);
.text : { *(.text) } >text AT>text :text

. = ALIGN(0x1000);
.data : { *(.data) } >data AT>data :data_init
.data.string : { *(.data.string)} >data AT>data :data_init
.bss : { *(.bss) } >data AT>data :data

. = ALIGN(0x1000);
.hostmmio : { *(.hostmmio) } >mmio AT>mmio :mmio

. = ALIGN(0x1000);
.signature : { *(.signature) } >signature AT>signature :signature

_end = .;
}
64 changes: 64 additions & 0 deletions test/external/riscof/coreblocks/env/model_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef _COMPLIANCE_MODEL_H
#define _COMPLIANCE_MODEL_H
#define RVMODEL_DATA_SECTION \
.pushsection .hostmmio,"aw",@progbits; \
.align 8; .global tohost; tohost: .dword 0; \
.align 8; .global fromhost; fromhost: .dword 0; \
.popsection; \
.align 8; .global begin_regstate; begin_regstate: \
.word 128; \
.align 8; .global end_regstate; end_regstate: \
.word 4;

//RV_COMPLIANCE_HALT
#define RVMODEL_HALT \
li x1, 1; \
write_tohost: \
sw x1, tohost, t5; \
j write_tohost;

#define RVMODEL_BOOT

//RV_COMPLIANCE_DATA_BEGIN
#define RVMODEL_DATA_BEGIN \
RVMODEL_DATA_SECTION \
.pushsection .signature,"aw",@progbits; \
.align 2; \
.global begin_signature; begin_signature:

//RV_COMPLIANCE_DATA_END
#define RVMODEL_DATA_END \
.global end_signature; end_signature: \
.popsection;

//RVTEST_IO_INIT
#define RVMODEL_IO_INIT
//RVTEST_IO_WRITE_STR
#define RVMODEL_IO_WRITE_STR(_R, _STR)
//RVTEST_IO_CHECK
#define RVMODEL_IO_CHECK()
//RVTEST_IO_ASSERT_GPR_EQ
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)
//RVTEST_IO_ASSERT_SFPR_EQ
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
//RVTEST_IO_ASSERT_DFPR_EQ
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)

// empty macros to supress warnings
#define RVMODEL_SET_MSW_INT
#define RVMODEL_CLEAR_MSW_INT
#define RVMODEL_CLEAR_MTIMER_INT
#define RVMODEL_CLEAR_MEXT_INT
#define RVMODEL_CLR_MSW_INT
#define RVMODEL_CLR_MTIMER_INT
#define RVMODEL_CLR_MEXT_INT
#define RVMODEL_SET_SSW_INT
#define RVMODEL_CLR_SSW_INT
#define RVMODEL_CLR_STIMER_INT
#define RVMODEL_CLR_SEXT_INT
#define RVMODEL_SET_VSW_INT
#define RVMODEL_CLR_VSW_INT
#define RVMODEL_CLR_VTIMER_INT
#define RVMODEL_CLR_VEXT_INT

#endif // _COMPLIANCE_MODEL_H
28 changes: 28 additions & 0 deletions test/regression/cocotb/signature.Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Makefile

# defaults
SIM ?= verilator
TOPLEVEL_LANG ?= verilog

VERILOG_SOURCES += $(PWD)/../../../core.v
# use VHDL_SOURCES for VHDL files

# TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file
TOPLEVEL = top

# MODULE is the basename of the Python test file
MODULE = signature_entrypoint

SIM_BUILD = build/signature

# Yosys/Amaranth borkedness workaround
ifeq ($(SIM),verilator)
EXTRA_ARGS += -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC
endif

ifeq ($(TRACES),1)
EXTRA_ARGS += --trace-fst --trace-structs
endif

# include cocotb's make rules to take care of the simulator setup
include $(shell cocotb-config --makefiles)/Makefile.sim
Loading

0 comments on commit 790365f

Please sign in to comment.