Skip to content

Commit

Permalink
Merge branch 'master' into lekcyjna/transactron-multi-method-request
Browse files Browse the repository at this point in the history
  • Loading branch information
tilk authored Nov 14, 2023
2 parents 6fe5d16 + 8454fb8 commit 2dccb4f
Show file tree
Hide file tree
Showing 80 changed files with 1,816 additions and 953 deletions.
45 changes: 37 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,39 @@ jobs:
name: Build regression tests
runs-on: ubuntu-latest
container: ghcr.io/kuznia-rdzeni/riscv-toolchain:2023.10.08_v
outputs:
cache_hit: ${{ steps.cache-regression.outputs.cache-hit }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Build riscv-tests
- name: Cache regression-tests
id: cache-regression
uses: actions/cache@v3
env:
cache-name: cache-regression-tests
with:
path: test/external/riscv-tests/test-*

key: ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(
'**/test/external/riscv-tests/environment/**',
'**/test/external/riscv-tests/Makefile',
'**/.git/modules/test/external/riscv-tests/riscv-tests/HEAD',
'**/docker/riscv-toolchain.Dockerfile'
) }}
restore-keys: |
${{ env.cache-name }}-${{ runner.os }}-
- if: ${{ steps.cache-regression.outputs.cache-hit != 'true' }}
run: cd test/external/riscv-tests && make

- uses: actions/upload-artifact@v3
- if: ${{ steps.cache-regression.outputs.cache-hit != 'true' }}
name: Upload riscv-tests
uses: actions/upload-artifact@v3
with:
name: "riscv-tests"
path: |
test/external/riscv-tests/test-*
path: test/external/riscv-tests

run-regression-tests:
name: Run regression tests
Expand All @@ -40,6 +59,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v4
Expand All @@ -58,10 +79,18 @@ jobs:
. venv/bin/activate
PYTHONHASHSEED=0 ./scripts/gen_verilog.py --verbose --config full
- uses: actions/download-artifact@v3
- uses: actions/cache@v3
env:
cache-name: cache-regression-tests
with:
name: "riscv-tests"
path: test/external/riscv-tests
path: test/external/riscv-tests/test-*
key: ${{ env.cache-name }}-${{ runner.os }}-${{ hashFiles(
'**/test/external/riscv-tests/environment/**',
'**/test/external/riscv-tests/Makefile',
'**/.git/modules/test/external/riscv-tests/riscv-tests/HEAD',
'**/docker/riscv-toolchain.Dockerfile'
) }}
fail-on-cache-miss: true

- name: Run tests
run: |
Expand Down
6 changes: 3 additions & 3 deletions coreblocks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from coreblocks.frontend.icache import ICache, SimpleWBCacheRefiller, ICacheBypass
from coreblocks.peripherals.wishbone import WishboneMaster, WishboneBus
from coreblocks.frontend.fetch import Fetch, UnalignedFetch
from coreblocks.utils.fifo import BasicFifo
from transactron.utils.fifo import BasicFifo

__all__ = ["Core"]

Expand Down Expand Up @@ -75,8 +75,8 @@ def __init__(self, *, gen_params: GenParams, wb_instr_bus: WishboneBus, wb_data_
gen=self.gen_params,
get_result=self.func_blocks_unifier.get_result,
rob_mark_done=self.ROB.mark_done,
rs_write_val=self.func_blocks_unifier.update,
rf_write_val=self.RF.write,
rs_update=self.func_blocks_unifier.update,
rf_write=self.RF.write,
)

self.csr_generic = GenericCSRRegisters(self.gen_params)
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/frontend/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def elaborate(self, platform):
with Transaction().body(m):
raw = self.get_raw(m)

m.d.top_comb += instr_decoder.instr.eq(raw.data)
m.d.top_comb += instr_decoder.instr.eq(raw.instr)

# Jump-branch unit requires information if the instruction was
# decoded from a compressed instruction. To avoid adding a new signal
Expand Down
6 changes: 3 additions & 3 deletions coreblocks/frontend/fetch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from amaranth import *
from coreblocks.utils.fifo import BasicFifo, Semaphore
from transactron.utils.fifo 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 Expand Up @@ -82,7 +82,7 @@ def stall():
m.d.sync += self.pc.eq(target.addr)
m.d.comb += instr.eq(res.instr)

self.cont(m, data=instr, pc=target.addr, access_fault=fetch_error, rvc=0)
self.cont(m, instr=instr, pc=target.addr, access_fault=fetch_error, rvc=0)

@def_method(m, self.verify_branch, ready=stalled)
def _(from_pc: Value, next_pc: Value):
Expand Down Expand Up @@ -210,7 +210,7 @@ def elaborate(self, platform) -> TModule:
with m.If(~cache_resp.error):
m.d.sync += current_pc.eq(current_pc + Mux(is_rvc, C(2, 3), C(4, 3)))

self.cont(m, data=instr, pc=current_pc, access_fault=cache_resp.error, rvc=is_rvc)
self.cont(m, instr=instr, pc=current_pc, access_fault=cache_resp.error, rvc=is_rvc)

@def_method(m, self.verify_branch, ready=(stalled & ~flushing))
def _(from_pc: Value, next_pc: Value):
Expand Down
25 changes: 19 additions & 6 deletions coreblocks/frontend/icache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from transactron.core import def_method, Priority, TModule
from transactron import Method, Transaction
from coreblocks.params import ICacheLayouts, ICacheParameters
from coreblocks.utils import assign, OneHotSwitchDynamic
from coreblocks.utils._typing import HasElaborate
from transactron.utils import assign, OneHotSwitchDynamic
from transactron.utils._typing import HasElaborate
from transactron.lib import *
from coreblocks.peripherals.wishbone import WishboneMaster

Expand Down Expand Up @@ -382,30 +382,43 @@ def elaborate(self, platform):
refill_active = Signal()
word_counter = Signal(range(self.params.words_in_block))

with Transaction().body(m, request=refill_active):
m.submodules.address_fwd = address_fwd = Forwarder(
[("word_counter", word_counter.shape()), ("refill_address", refill_address.shape())]
)

with Transaction().body(m):
address = address_fwd.read(m)
self.wb_master.request(
m,
addr=Cat(word_counter, refill_address),
addr=Cat(address["word_counter"], address["refill_address"]),
data=0,
we=0,
sel=Repl(1, self.wb_master.wb_params.data_width // self.wb_master.wb_params.granularity),
)

@def_method(m, self.start_refill, ready=~refill_active)
def _(addr) -> None:
m.d.sync += refill_address.eq(addr[self.params.offset_bits :])
address = addr[self.params.offset_bits :]
m.d.sync += refill_address.eq(address)
m.d.sync += refill_active.eq(1)
m.d.sync += word_counter.eq(0)

address_fwd.write(m, word_counter=0, refill_address=address)

@def_method(m, self.accept_refill, ready=refill_active)
def _():
fetched = self.wb_master.result(m)

last = (word_counter == (self.params.words_in_block - 1)) | fetched.err

m.d.sync += word_counter.eq(word_counter + 1)
next_word_counter = Signal.like(word_counter)
m.d.top_comb += next_word_counter.eq(word_counter + 1)

m.d.sync += word_counter.eq(next_word_counter)
with m.If(last):
m.d.sync += refill_active.eq(0)
with m.Else():
address_fwd.write(m, word_counter=next_word_counter, refill_address=refill_address)

return {
"addr": Cat(Repl(0, log2_int(self.params.word_width_bytes)), word_counter, refill_address),
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/frontend/rvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from transactron import TModule
from coreblocks.params import *
from coreblocks.utils import ValueLike
from transactron.utils import ValueLike


# An instruction or an instruction with the valid signal
Expand Down
4 changes: 2 additions & 2 deletions coreblocks/fu/alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from transactron.lib import FIFO

from coreblocks.params import OpType, Funct3, Funct7, GenParams, FuncUnitLayouts, FunctionalComponentParams
from coreblocks.utils import HasElaborate, OneHotSwitch
from transactron.utils import HasElaborate, OneHotSwitch

from coreblocks.fu.fu_decoder import DecoderManager
from enum import IntFlag, auto

from coreblocks.utils.protocols import FuncUnit

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

__all__ = ["AluFuncUnit", "ALUComponent"]

Expand Down
4 changes: 2 additions & 2 deletions coreblocks/fu/div_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

from coreblocks.fu.fu_decoder import DecoderManager

from coreblocks.utils import OneHotSwitch
from coreblocks.utils.fifo import BasicFifo
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/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from transactron.lib import FIFO

from coreblocks.params import OpType, GenParams, FuncUnitLayouts, FunctionalComponentParams
from coreblocks.utils import OneHotSwitch
from transactron.utils import OneHotSwitch
from coreblocks.params.keys import ExceptionReportKey

from coreblocks.fu.fu_decoder import DecoderManager
Expand Down
92 changes: 39 additions & 53 deletions coreblocks/fu/fu_decoder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Sequence, Type
from amaranth import *

from coreblocks.params import GenParams, CommonLayouts
from coreblocks.params import GenParams, CommonLayoutFields

from enum import IntFlag

Expand All @@ -19,9 +19,9 @@ class Decoder(Elaboratable):
"""

def __init__(self, gen_params: GenParams, decode_fn: Type[IntFlag], ops: Sequence[tuple], check_optype: bool):
layouts = gen_params.get(CommonLayouts)
layouts = gen_params.get(CommonLayoutFields)

self.exec_fn = Record(layouts.exec_fn)
self.exec_fn = Record(layouts.exec_fn_layout)
self.decode_fn = Signal(decode_fn)
self.ops = ops
self.check_optype = check_optype
Expand All @@ -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 : Decoder
Instance of Decoder class.
"""
# 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)
2 changes: 1 addition & 1 deletion coreblocks/fu/jumpbranch.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from transactron.lib import *

from coreblocks.params import *
from coreblocks.utils import OneHotSwitch
from transactron.utils import OneHotSwitch
from coreblocks.utils.protocols import FuncUnit

from coreblocks.fu.fu_decoder import DecoderManager
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/fu/mul_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

__all__ = ["MulUnit", "MulFn", "MulComponent", "MulType"]

from coreblocks.utils import OneHotSwitch
from transactron.utils import OneHotSwitch
from coreblocks.utils.protocols import FuncUnit


Expand Down
2 changes: 1 addition & 1 deletion coreblocks/fu/shift_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from transactron.lib import FIFO

from coreblocks.params import OpType, Funct3, Funct7, GenParams, FuncUnitLayouts, FunctionalComponentParams
from coreblocks.utils import OneHotSwitch
from transactron.utils import OneHotSwitch

from coreblocks.fu.fu_decoder import DecoderManager
from enum import IntFlag, auto
Expand Down
Loading

0 comments on commit 2dccb4f

Please sign in to comment.