Skip to content

Commit

Permalink
Merge branch 'master' into async-interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
piotro888 committed Dec 16, 2023
2 parents 9f4498f + 9e99b5b commit b302b08
Show file tree
Hide file tree
Showing 49 changed files with 1,082 additions and 743 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
- name: Generate Verilog
run: |
. venv/bin/activate
PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full
PYTHONHASHSEED=0 TRANSACTRON_VERBOSE=1 ./scripts/gen_verilog.py --verbose --config full
- uses: actions/download-artifact@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Generate Verilog
run: |
. venv/bin/activate
PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full
PYTHONHASHSEED=0 TRANSACTRON_VERBOSE=1 ./scripts/gen_verilog.py --verbose --config full
- uses: actions/upload-artifact@v3
with:
Expand Down
3 changes: 2 additions & 1 deletion coreblocks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from coreblocks.peripherals.wishbone import WishboneMaster, WishboneBus
from coreblocks.frontend.fetch import Fetch, UnalignedFetch
from transactron.lib.transformers import MethodMap, MethodProduct
from transactron.utils.fifo import BasicFifo
from transactron.lib import BasicFifo

__all__ = ["Core"]

Expand Down Expand Up @@ -152,6 +152,7 @@ def elaborate(self, platform):
rf_free=rf.free,
precommit=self.func_blocks_unifier.get_extra_method(InstructionPrecommitKey()),
exception_cause_get=self.exception_cause_register.get,
exception_cause_clear=self.exception_cause_register.clear,
frat_rename=frat.rename,
fetch_continue=self.fetch.verify_branch,
fetch_stall=self.fetch.stall_exception,
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/frontend/fetch.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from amaranth import *
from transactron.core import Priority
from transactron.utils.fifo import BasicFifo, Semaphore
from transactron.lib import BasicFifo, Semaphore
from coreblocks.frontend.icache import ICacheInterface
from coreblocks.frontend.rvc import InstrDecompress, is_instr_compressed
from transactron import def_method, Method, Transaction, TModule
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/fu/alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from coreblocks.utils.protocols import FuncUnit

from transactron.utils.utils import popcount, count_leading_zeros
from transactron.utils import popcount, count_leading_zeros

__all__ = ["AluFuncUnit", "ALUComponent"]

Expand Down
1 change: 0 additions & 1 deletion coreblocks/fu/div_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from coreblocks.fu.fu_decoder import DecoderManager

from transactron.utils import OneHotSwitch
from transactron.utils.fifo import BasicFifo
from coreblocks.utils.protocols import FuncUnit
from coreblocks.fu.division.long_division import LongDivider

Expand Down
2 changes: 1 addition & 1 deletion coreblocks/fu/priv.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


from transactron import *
from transactron.utils.fifo import BasicFifo
from transactron.lib import BasicFifo

from coreblocks.params import *
from coreblocks.params.keys import MretKey
Expand Down
18 changes: 14 additions & 4 deletions coreblocks/lsu/dummyLsu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from transactron.utils import assign, ModuleLike
from coreblocks.utils.protocols import FuncBlock

from coreblocks.lsu.pma import PMAChecker

__all__ = ["LSUDummy", "LSUBlockComponent"]

Expand Down Expand Up @@ -200,11 +201,12 @@ def elaborate(self, platform):
m = TModule()
reserved = Signal() # current_instr is reserved
valid = Signal() # current_instr is valid
execute = Signal() # start execution
precommiting = Signal() # start execution
issued = Signal() # instruction was issued to the bus
flush = Signal() # exception handling, requests are not issued
current_instr = Record(self.lsu_layouts.rs.data_layout)

m.submodules.pma_checker = pma_checker = PMAChecker(self.gen_params)
m.submodules.requester = requester = LSURequesterWB(self.gen_params, self.bus)

m.submodules.results = results = self.forwarder = Forwarder(self.lsu_layouts.accept)
Expand All @@ -217,6 +219,12 @@ def elaborate(self, platform):
instr_is_load = Signal()
m.d.comb += instr_is_load.eq(current_instr.exec_fn.op_type == OpType.LOAD)

addr = Signal(self.gen_params.isa.xlen)
m.d.comb += addr.eq(current_instr.s1_val + current_instr.imm)

m.d.comb += pma_checker.addr.eq(addr)
pmas = pma_checker.result

@def_method(m, self.select, ~reserved)
def _():
# We always return 0, because we have only one place in instruction storage.
Expand All @@ -239,12 +247,14 @@ def _(reg_id: Value, reg_val: Value):

# Issues load/store requests when the instruction is known, is a LOAD/STORE, and just before commit.
# Memory loads can be issued speculatively.
do_issue = ~issued & instr_ready & ~flush & ~instr_is_fence & (execute | instr_is_load)
can_reorder = instr_is_load & ~pmas["mmio"]
want_issue = ~instr_is_fence & (precommiting | can_reorder)
do_issue = ~issued & instr_ready & ~flush & want_issue
with Transaction().body(m, request=do_issue):
m.d.sync += issued.eq(1)
res = requester.issue(
m,
addr=current_instr.s1_val + current_instr.imm,
addr=addr,
data=current_instr.s2_val,
funct3=current_instr.exec_fn.funct3,
store=~instr_is_load,
Expand Down Expand Up @@ -285,7 +295,7 @@ def _(rob_id: Value, side_fx: Value):
with m.If(~side_fx):
m.d.comb += flush.eq(1)
with m.Elif(valid & (rob_id == current_instr.rob_id) & ~instr_is_fence):
m.d.comb += execute.eq(1)
m.d.comb += precommiting.eq(1)

return m

Expand Down
69 changes: 69 additions & 0 deletions coreblocks/lsu/pma.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from dataclasses import dataclass
from functools import reduce
from operator import or_
from amaranth import *

from coreblocks.params import *
from transactron.utils import HasElaborate
from transactron.core import TModule


@dataclass
class PMARegion:
"""
Data class for physical memory attributes contiguous region of memory. Region of memory
includes both start and end address.
Attributes
----------
start : int
Defines beginning of region, start address is included in the region.
end : int
Defines end of region, end address is included in the region.
mmio : bool
Value True for this field indicates that memory region is MMIO.
"""

start: int
end: int
mmio: bool = False


class PMAChecker(Elaboratable):
"""
Implementation of physical memory attributes checker. It may or may not be a part of LSU.
This is a combinational circuit with return value read from `result` output.
Attributes
----------
addr : Signal
Memory address, for which PMAs are requested.
result : Record
PMAs for given address.
"""

def __init__(self, gen_params: GenParams) -> None:
# poor man's interval list
self.segments = gen_params.pma
self.attr_layout = gen_params.get(PMALayouts).pma_attrs_layout
self.result = Record(self.attr_layout)
self.addr = Signal(gen_params.isa.xlen)

def elaborate(self, platform) -> HasElaborate:
m = TModule()

outputs = [Record(self.attr_layout) for _ in self.segments]

# zero output if addr not in region, propagate value if addr in region
for i, segment in enumerate(self.segments):
start = segment.start
end = segment.end

# check if addr in region
with m.If((self.addr >= start) & (self.addr <= end)):
m.d.comb += outputs[i].eq(segment.mmio)

# OR all outputs
m.d.comb += self.result.eq(reduce(or_, outputs, 0))

return m
8 changes: 7 additions & 1 deletion coreblocks/params/configurations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from collections.abc import Collection

import dataclasses
from dataclasses import dataclass
from dataclasses import dataclass, field
from coreblocks.lsu.pma import PMARegion

from coreblocks.params.isa import Extension
from coreblocks.params.fu_params import BlockComponentParams
Expand Down Expand Up @@ -64,6 +66,8 @@ class CoreConfiguration:
Allow partial support of extensions.
_implied_extensions: Extenstion
Bit flag specifing enabled extenstions that are not specified by func_units_config. Used in internal tests.
pma : list[PMARegion]
Definitions of PMAs per contiguous segments of memory.
"""

xlen: int = 32
Expand All @@ -85,6 +89,8 @@ class CoreConfiguration:

_implied_extensions: Extension = Extension(0)

pma: list[PMARegion] = field(default_factory=list)

def replace(self, **kwargs):
return dataclasses.replace(self, **kwargs)

Expand Down
2 changes: 2 additions & 0 deletions coreblocks/params/genparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def __init__(self, cfg: CoreConfiguration):

self.isa = ISA(self.isa_str)

self.pma = cfg.pma

bytes_in_word = self.isa.xlen // 8
self.wb_params = WishboneParameters(
data_width=self.isa.xlen, addr_width=self.isa.xlen - log2_int(bytes_in_word)
Expand Down
9 changes: 7 additions & 2 deletions coreblocks/params/layouts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from coreblocks.params import GenParams, OpType, Funct7, Funct3
from coreblocks.params.isa import ExceptionCause
from transactron.utils.utils import layout_subset
from transactron.utils import LayoutList, LayoutListField
from transactron.utils import LayoutList, LayoutListField, layout_subset

__all__ = [
"CommonLayoutFields",
Expand All @@ -17,6 +16,7 @@
"UnsignedMulUnitLayouts",
"RATLayouts",
"LSULayouts",
"PMALayouts",
"CSRLayouts",
"ICacheLayouts",
]
Expand Down Expand Up @@ -540,6 +540,11 @@ def __init__(self, gen_params: GenParams):
self.accept: LayoutList = [fields.data, fields.exception, fields.cause]


class PMALayouts:
def __init__(self, gen_params: GenParams):
self.pma_attrs_layout = [("mmio", 1)]


class CSRLayouts:
"""Layouts used in the control and status registers."""

Expand Down
5 changes: 2 additions & 3 deletions coreblocks/peripherals/wishbone.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@

from transactron import Method, def_method, TModule
from transactron.core import Transaction
from transactron.lib import AdapterTrans
from transactron.utils.utils import OneHotSwitchDynamic, assign
from transactron.utils.fifo import BasicFifo
from transactron.lib import AdapterTrans, BasicFifo
from transactron.utils import OneHotSwitchDynamic, assign
from transactron.lib.connectors import Forwarder


Expand Down
5 changes: 5 additions & 0 deletions coreblocks/stages/retirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(
rf_free: Method,
precommit: Method,
exception_cause_get: Method,
exception_cause_clear: Method,
frat_rename: Method,
fetch_continue: Method,
fetch_stall: Method,
Expand All @@ -36,6 +37,7 @@ def __init__(
self.rf_free = rf_free
self.precommit = precommit
self.exception_cause_get = exception_cause_get
self.exception_cause_clear = exception_cause_clear
self.rename = frat_rename
self.fetch_continue = fetch_continue
self.fetch_stall = fetch_stall
Expand Down Expand Up @@ -134,6 +136,9 @@ def elaborate(self, platform):
resume_pc = m_csr.mtvec.read(m) & ~(0b11)
fetch_continue_fwd.write(m, pc=resume_pc)

# Release pending trap state - allow accepting new reports
self.exception_cause_clear(m)

m.d.sync += side_fx.eq(1)

with Transaction().body(m):
Expand Down
4 changes: 1 addition & 3 deletions coreblocks/structs_common/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from coreblocks.params.isa import ExceptionCause
from coreblocks.params.layouts import ExceptionRegisterLayouts
from coreblocks.params.keys import ExceptionReportKey
from transactron.core import Priority, TModule, def_method, Method
from transactron.core import TModule, def_method, Method


def should_update_prioriy(m: TModule, current_cause: Value, new_cause: Value) -> Value:
Expand Down Expand Up @@ -62,8 +62,6 @@ def __init__(self, gp: GenParams, rob_get_indices: Method):

self.clear = Method()

self.clear.add_conflict(self.report, Priority.LEFT)

self.rob_get_indices = rob_get_indices

def elaborate(self, platform):
Expand Down
2 changes: 1 addition & 1 deletion scripts/gen_verilog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from coreblocks.peripherals.wishbone import WishboneBus
from coreblocks.core import Core
from transactron import TransactionModule
from transactron.utils.utils import flatten_signals
from transactron.utils import flatten_signals

from coreblocks.params.configurations import *

Expand Down
2 changes: 1 addition & 1 deletion scripts/synthesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
sys.path.insert(0, parent)


from transactron.utils.utils import ModuleConnector
from transactron.utils import ModuleConnector
from coreblocks.params.genparams import GenParams
from coreblocks.params.fu_params import FunctionalComponentParams
from coreblocks.core import Core
Expand Down
27 changes: 27 additions & 0 deletions test/asm/exception_handler.asm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ loop:
mv x1, x2
mv x2, x3
bne x2, x4, loop

# report another exception after full rob_idx overflow
# so it has the same rob index as previous report
li x10, 0
li x11, 13
rob_loop:
addi x10, x10, 1
nop
nop
nop
nop
nop
nop
bne x10, x11, rob_loop

nop
nop
nop
nop
nop
nop
nop

.4byte 0 # exception

li x11, 0xaaaa # verify exception return

infloop:
j infloop

Expand Down
2 changes: 1 addition & 1 deletion test/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
from .infrastructure import * # noqa: F401
from .sugar import * # noqa: F401
from .testbenchio import * # noqa: F401
from transactron._utils import data_layout # noqa: F401
from transactron.utils import data_layout # noqa: F401
2 changes: 1 addition & 1 deletion test/common/testbenchio.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Optional, Callable
from transactron.lib import AdapterBase
from transactron.core import ValueLike, SignalBundle
from transactron._utils import mock_def_helper
from transactron.utils import mock_def_helper
from transactron.utils._typing import RecordIntDictRet, RecordValueDict, RecordIntDict
from .functions import set_inputs, get_outputs, TestGen

Expand Down
2 changes: 1 addition & 1 deletion test/fu/test_alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from test.fu.functional_common import ExecFn, FunctionalUnitTestCase

from transactron._utils import signed_to_int
from transactron.utils import signed_to_int


class AluUnitTest(FunctionalUnitTestCase[AluFn.Fn]):
Expand Down
Loading

0 comments on commit b302b08

Please sign in to comment.