Skip to content

Commit

Permalink
Merge branch 'master' into piotro/u-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
piotro888 committed Oct 8, 2024
2 parents 365b704 + 87cb8f5 commit 180232f
Show file tree
Hide file tree
Showing 81 changed files with 606 additions and 537 deletions.
4 changes: 2 additions & 2 deletions coreblocks/backend/retirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def elaborate(self, platform):
m_csr = self.dependency_manager.get_dependency(CSRInstancesKey()).m_mode
m.submodules.instret_csr = self.instret_csr

side_fx = Signal(reset=1)
side_fx = Signal(init=1)

def free_phys_reg(rp_dst: Value):
# mark reg in Register File as free
Expand Down Expand Up @@ -129,7 +129,7 @@ def flush_instr(rob_entry):

cause_entry = Signal(self.gen_params.isa.xlen)

arch_trap = Signal(reset=1)
arch_trap = Signal(init=1)

with m.If(cause_register.cause == ExceptionCause._COREBLOCKS_ASYNC_INTERRUPT):
# Async interrupts are inserted only by JumpBranchUnit and conditionally by MRET and CSR
Expand Down
27 changes: 13 additions & 14 deletions coreblocks/cache/icache.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from amaranth import *
from amaranth.lib.data import View
import amaranth.lib.memory as memory
from amaranth.utils import exact_log2

from transactron.core import def_method, Priority, TModule
Expand Down Expand Up @@ -156,7 +157,7 @@ def elaborate(self, platform):
with Transaction().body(m):
self.perf_flushes.incr(m, cond=flush_finish)

with m.FSM(reset="FLUSH") as fsm:
with m.FSM(init="FLUSH") as fsm:
with m.State("FLUSH"):
with m.If(flush_finish):
m.next = "LOOKUP"
Expand All @@ -172,7 +173,7 @@ def elaborate(self, platform):
m.next = "LOOKUP"

# Replacement policy
way_selector = Signal(self.params.num_of_ways, reset=1)
way_selector = Signal(self.params.num_of_ways, init=1)
with m.If(refill_finish):
m.d.sync += way_selector.eq(way_selector.rotate_left(1))

Expand Down Expand Up @@ -329,27 +330,25 @@ def elaborate(self, platform):
for i in range(self.params.num_of_ways):
way_wr = self.way_wr_en[i]

tag_mem = Memory(width=len(Value.cast(self.tag_wr_data)), depth=self.params.num_of_sets)
tag_mem_rp = tag_mem.read_port()
tag_mem = memory.Memory(shape=self.tag_data_layout, depth=self.params.num_of_sets, init=[])
tag_mem_wp = tag_mem.write_port()
m.submodules[f"tag_mem_{i}_rp"] = tag_mem_rp
m.submodules[f"tag_mem_{i}_wp"] = tag_mem_wp
tag_mem_rp = tag_mem.read_port(transparent_for=[tag_mem_wp])
m.submodules[f"tag_mem_{i}"] = tag_mem

m.d.comb += [ # remove Value.cast after Amaranth upgrade
assign(Value.cast(self.tag_rd_data[i]), tag_mem_rp.data),
m.d.comb += [
assign(self.tag_rd_data[i], tag_mem_rp.data),
tag_mem_rp.addr.eq(self.tag_rd_index),
tag_mem_wp.addr.eq(self.tag_wr_index),
assign(tag_mem_wp.data, Value.cast(self.tag_wr_data)),
assign(tag_mem_wp.data, self.tag_wr_data),
tag_mem_wp.en.eq(self.tag_wr_en & way_wr),
]

data_mem = Memory(
width=self.fetch_block_bits, depth=self.params.num_of_sets * self.params.fetch_blocks_in_line
data_mem = memory.Memory(
shape=self.fetch_block_bits, depth=self.params.num_of_sets * self.params.fetch_blocks_in_line, init=[]
)
data_mem_rp = data_mem.read_port()
data_mem_wp = data_mem.write_port()
m.submodules[f"data_mem_{i}_rp"] = data_mem_rp
m.submodules[f"data_mem_{i}_wp"] = data_mem_wp
data_mem_rp = data_mem.read_port(transparent_for=[data_mem_wp])
m.submodules[f"data_mem_{i}"] = data_mem

# We address the data RAM using fetch blocks, so we have to
# discard a few least significant bits from the address.
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def elaborate(self, platform):
)

# push all registers to FreeRF at reset. r0 should be skipped, stop when counter overflows to 0
free_rf_reg = Signal(self.gen_params.phys_regs_bits, reset=1)
free_rf_reg = Signal(self.gen_params.phys_regs_bits, init=1)
with Transaction(name="InitFreeRFFifo").body(m, request=(free_rf_reg.bool())):
free_rf_fifo.write(m, free_rf_reg)
m.d.sync += free_rf_reg.eq(free_rf_reg + 1)
Expand Down
19 changes: 9 additions & 10 deletions coreblocks/core_structs/rf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ def __init__(self, *, gen_params: GenParams):
layouts = gen_params.get(RFLayouts)
self.internal_layout = make_layout(("reg_val", gen_params.isa.xlen), ("valid", 1))
self.read_layout = layouts.rf_read_out
self.entries = Array(Signal(self.internal_layout) for _ in range(2**gen_params.phys_regs_bits))
self.entries = Array(
Signal(self.internal_layout, reset={"reg_val": 0, "valid": k == 0})
for k in range(2**gen_params.phys_regs_bits)
)

self.read1 = Method(i=layouts.rf_read_in, o=layouts.rf_read_out)
self.read2 = Method(i=layouts.rf_read_in, o=layouts.rf_read_out)
Expand Down Expand Up @@ -43,23 +46,19 @@ def elaborate(self, platform):
being_written = Signal(self.gen_params.phys_regs_bits)
written_value = Signal(self.gen_params.isa.xlen)

# Register 0 always valid (this field won't be updated in methods below) - not sure
# how to set 0th entry valid signal at initialization stage so doing it here instead
# with a 1-cycle delay. I believe this has to be in sync domain like every other
# RF entry or else bad things will happen.
m.d.sync += self.entries[0].valid.eq(1)

@def_method(m, self.read1)
def _(reg_id: Value):
forward = being_written == reg_id
forward = Signal()
m.d.av_comb += forward.eq((being_written == reg_id) & (reg_id != 0))
return {
"reg_val": Mux(forward, written_value, self.entries[reg_id].reg_val),
"valid": Mux(forward, 1, self.entries[reg_id].valid),
}

@def_method(m, self.read2)
def _(reg_id: Value):
forward = being_written == reg_id
forward = Signal()
m.d.av_comb += forward.eq((being_written == reg_id) & (reg_id != 0))
return {
"reg_val": Mux(forward, written_value, self.entries[reg_id].reg_val),
"valid": Mux(forward, 1, self.entries[reg_id].valid),
Expand All @@ -69,7 +68,7 @@ def _(reg_id: Value):
def _(reg_id: Value, reg_val: Value):
zero_reg = reg_id == 0
m.d.comb += being_written.eq(reg_id)
m.d.comb += written_value.eq(Mux(zero_reg, 0, reg_val))
m.d.av_comb += written_value.eq(reg_val)
with m.If(~(zero_reg)):
m.d.sync += self.entries[reg_id].reg_val.eq(reg_val)
m.d.sync += self.entries[reg_id].valid.eq(1)
Expand Down
8 changes: 5 additions & 3 deletions coreblocks/core_structs/rob.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from amaranth import *
from amaranth.lib.data import View
import amaranth.lib.memory as memory
from transactron import Method, Transaction, def_method, TModule
from transactron.lib.metrics import *
from coreblocks.interface.layouts import ROBLayouts
Expand All @@ -18,7 +19,7 @@ def __init__(self, gen_params: GenParams) -> None:
self.retire = Method()
self.done = Array(Signal() for _ in range(2**self.params.rob_entries_bits))
self.exception = Array(Signal() for _ in range(2**self.params.rob_entries_bits))
self.data = Memory(width=layouts.data_layout.size, depth=2**self.params.rob_entries_bits)
self.data = memory.Memory(shape=layouts.data_layout.size, depth=2**self.params.rob_entries_bits, init=[])
self.get_indices = Method(o=layouts.get_indices, nonexclusive=True)

self.perf_rob_wait_time = FIFOLatencyMeasurer(
Expand All @@ -45,8 +46,9 @@ def elaborate(self, platform):
peek_possible = start_idx != end_idx
put_possible = (end_idx + 1)[0 : len(end_idx)] != start_idx

m.submodules.read_port = read_port = self.data.read_port()
m.submodules.write_port = write_port = self.data.write_port()
m.submodules.data = self.data
write_port = self.data.write_port()
read_port = self.data.read_port(transparent_for=[write_port])

m.d.comb += read_port.addr.eq(start_idx)

Expand Down
2 changes: 1 addition & 1 deletion coreblocks/frontend/fetch/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def elaborate(self, platform):
def flush():
m.d.comb += flush_now.eq(1)

current_pc = Signal(self.gen_params.isa.xlen, reset=self.gen_params.start_pc)
current_pc = Signal(self.gen_params.isa.xlen, init=self.gen_params.start_pc)

stalled_unsafe = Signal()
stalled_exception = Signal()
Expand Down
8 changes: 4 additions & 4 deletions coreblocks/func_blocks/fu/alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ def _():

@def_method(m, self.issue)
def _(arg):
m.d.comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.comb += alu.fn.eq(decoder.decode_fn)
m.d.av_comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.av_comb += alu.fn.eq(decoder.decode_fn)

m.d.comb += alu.in1.eq(arg.s1_val)
m.d.comb += alu.in2.eq(Mux(arg.imm, arg.imm, arg.s2_val))
m.d.av_comb += alu.in1.eq(arg.s1_val)
m.d.av_comb += alu.in2.eq(Mux(arg.imm, arg.imm, arg.s2_val))

self.perf_instr.incr(m, decoder.decode_fn)

Expand Down
5 changes: 5 additions & 0 deletions coreblocks/func_blocks/fu/common/rs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from abc import abstractmethod
from collections.abc import Iterable
from typing import Optional
from amaranth import *
Expand Down Expand Up @@ -59,6 +60,10 @@ def __init__(
sample_width=self.rs_entries_bits + 1,
)

@abstractmethod
def elaborate(self, platform) -> TModule:
raise NotImplementedError

def _elaborate(self, m: TModule, selected_id: Value, select_possible: Value, take_vector: Value):
m.submodules += [self.perf_rs_wait_time, self.perf_num_full]

Expand Down
34 changes: 17 additions & 17 deletions coreblocks/func_blocks/fu/div_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def _():

@def_method(m, self.issue)
def _(arg):
m.d.comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.av_comb += decoder.exec_fn.eq(arg.exec_fn)
i1, i2 = get_input(arg)

flip_sign = Signal(1) # if result is negative number
Expand All @@ -98,27 +98,27 @@ def _abs(s: Value) -> Value:

with OneHotSwitch(m, decoder.decode_fn) as OneHotCase:
with OneHotCase(DivFn.Fn.DIVU):
m.d.comb += flip_sign.eq(0)
m.d.comb += rem_res.eq(0)
m.d.comb += dividend.eq(i1)
m.d.comb += divisor.eq(i2)
m.d.av_comb += flip_sign.eq(0)
m.d.av_comb += rem_res.eq(0)
m.d.av_comb += dividend.eq(i1)
m.d.av_comb += divisor.eq(i2)
with OneHotCase(DivFn.Fn.DIV):
# quotient is negative if divisor and dividend have different signs
m.d.comb += flip_sign.eq(i1[sign_bit] ^ i2[sign_bit])
m.d.comb += rem_res.eq(0)
m.d.comb += dividend.eq(_abs(i1))
m.d.comb += divisor.eq(_abs(i2))
m.d.av_comb += flip_sign.eq(i1[sign_bit] ^ i2[sign_bit])
m.d.av_comb += rem_res.eq(0)
m.d.av_comb += dividend.eq(_abs(i1))
m.d.av_comb += divisor.eq(_abs(i2))
with OneHotCase(DivFn.Fn.REMU):
m.d.comb += flip_sign.eq(0)
m.d.comb += rem_res.eq(1)
m.d.comb += dividend.eq(i1)
m.d.comb += divisor.eq(i2)
m.d.av_comb += flip_sign.eq(0)
m.d.av_comb += rem_res.eq(1)
m.d.av_comb += dividend.eq(i1)
m.d.av_comb += divisor.eq(i2)
with OneHotCase(DivFn.Fn.REM):
# sign of remainder is equal to sign of dividend
m.d.comb += flip_sign.eq(i1[sign_bit])
m.d.comb += rem_res.eq(1)
m.d.comb += dividend.eq(_abs(i1))
m.d.comb += divisor.eq(_abs(i2))
m.d.av_comb += flip_sign.eq(i1[sign_bit])
m.d.av_comb += rem_res.eq(1)
m.d.av_comb += dividend.eq(_abs(i1))
m.d.av_comb += divisor.eq(_abs(i2))

params_fifo.write(m, rob_id=arg.rob_id, rp_dst=arg.rp_dst, flip_sign=flip_sign, rem_res=rem_res)

Expand Down
2 changes: 1 addition & 1 deletion coreblocks/func_blocks/fu/division/long_division.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def elaborate(self, platform):
self.ipc, xlen, partial_remainder_count=self.partial_remainder_count
)

ready = Signal(1, reset=1)
ready = Signal(1, init=1)

dividend = Signal(unsigned(xlen))
divisor = Signal(unsigned(xlen))
Expand Down
34 changes: 17 additions & 17 deletions coreblocks/func_blocks/fu/mul_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def _():

@def_method(m, self.issue)
def _(arg):
m.d.comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.av_comb += decoder.exec_fn.eq(arg.exec_fn)
i1, i2 = get_input(arg)

value1 = Signal(self.gen_params.isa.xlen) # input value for multiplier submodule
Expand All @@ -161,25 +161,25 @@ def _(arg):
# In this case we care only about lower part of number, so it does not matter if it is
# interpreted as binary number or U2 encoded number, so we set result to be interpreted as
# non-negative number.
m.d.comb += negative_res.eq(0)
m.d.comb += high_res.eq(0)
m.d.comb += value1.eq(i1)
m.d.comb += value2.eq(i2)
m.d.av_comb += negative_res.eq(0)
m.d.av_comb += high_res.eq(0)
m.d.av_comb += value1.eq(i1)
m.d.av_comb += value2.eq(i2)
with OneHotCase(MulFn.Fn.MULH):
m.d.comb += negative_res.eq(i1[sign_bit] ^ i2[sign_bit])
m.d.comb += high_res.eq(1)
m.d.comb += value1.eq(Mux(i1[sign_bit], -i1, i1))
m.d.comb += value2.eq(Mux(i2[sign_bit], -i2, i2))
m.d.av_comb += negative_res.eq(i1[sign_bit] ^ i2[sign_bit])
m.d.av_comb += high_res.eq(1)
m.d.av_comb += value1.eq(Mux(i1[sign_bit], -i1, i1))
m.d.av_comb += value2.eq(Mux(i2[sign_bit], -i2, i2))
with OneHotCase(MulFn.Fn.MULHU):
m.d.comb += negative_res.eq(0)
m.d.comb += high_res.eq(1)
m.d.comb += value1.eq(i1)
m.d.comb += value2.eq(i2)
m.d.av_comb += negative_res.eq(0)
m.d.av_comb += high_res.eq(1)
m.d.av_comb += value1.eq(i1)
m.d.av_comb += value2.eq(i2)
with OneHotCase(MulFn.Fn.MULHSU):
m.d.comb += negative_res.eq(i1[sign_bit])
m.d.comb += high_res.eq(1)
m.d.comb += value1.eq(Mux(i1[sign_bit], -i1, i1))
m.d.comb += value2.eq(i2)
m.d.av_comb += negative_res.eq(i1[sign_bit])
m.d.av_comb += high_res.eq(1)
m.d.av_comb += value1.eq(Mux(i1[sign_bit], -i1, i1))
m.d.av_comb += value2.eq(i2)
# Prepared for RV64
#
# with OneHotCase(MulFn.Fn.MULW):
Expand Down
8 changes: 4 additions & 4 deletions coreblocks/func_blocks/fu/shift_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ def _():

@def_method(m, self.issue)
def _(arg):
m.d.comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.comb += shift_alu.fn.eq(decoder.decode_fn)
m.d.av_comb += decoder.exec_fn.eq(arg.exec_fn)
m.d.av_comb += shift_alu.fn.eq(decoder.decode_fn)

m.d.comb += shift_alu.in1.eq(arg.s1_val)
m.d.comb += shift_alu.in2.eq(Mux(arg.imm, arg.imm, arg.s2_val))
m.d.av_comb += shift_alu.in1.eq(arg.s1_val)
m.d.av_comb += shift_alu.in2.eq(Mux(arg.imm, arg.imm, arg.s2_val))

fifo.write(m, rob_id=arg.rob_id, result=shift_alu.out, rp_dst=arg.rp_dst, exception=0)

Expand Down
5 changes: 5 additions & 0 deletions coreblocks/func_blocks/fu/unsigned_multiplication/common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from abc import abstractmethod
from amaranth import *

from coreblocks.params import GenParams
Expand Down Expand Up @@ -35,6 +36,10 @@ def __init__(self, gen_params: GenParams, dsp_width: int = 32):
self.issue = Method(i=layout.issue)
self.accept = Method(o=layout.accept)

@abstractmethod
def elaborate(self, platform) -> TModule:
raise NotImplementedError()


class DSPMulUnit(Elaboratable):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, dsp_width: int, dsp_number: int, n: int):

self.ready = Signal()
self.issue = Signal()
self.step = Signal(range(self.number_of_steps + 1), reset=self.number_of_steps)
self.step = Signal(range(self.number_of_steps + 1), init=self.number_of_steps)
self.i1 = Signal(self.n_padding)
self.i2 = Signal(self.n_padding)
self.result = Signal(2 * n)
Expand Down
4 changes: 2 additions & 2 deletions coreblocks/func_blocks/fu/unsigned_multiplication/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(self, dsp: DSPMulUnit, n: int):
self.i1 = Signal(unsigned(n))
self.i2 = Signal(unsigned(n))
self.result = Signal(unsigned(n * 2))
self.confirm = Signal(reset=0)
self.confirm = Signal()
self.reset = Signal()

def elaborate(self, platform) -> TModule:
Expand Down Expand Up @@ -135,7 +135,7 @@ def elaborate(self, platform):
m.submodules.dsp = dsp = DSPMulUnit(self.dsp_width)
m.submodules.multiplier = multiplier = RecursiveWithSingleDSPMul(dsp, self.gen_params.isa.xlen)

accepted = Signal(1, reset=1)
accepted = Signal(1, init=1)
m.d.sync += multiplier.reset.eq(0)

@def_method(m, self.issue, ready=accepted)
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/func_blocks/fu/unsigned_multiplication/shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def elaborate(self, platform):

i1 = Signal(unsigned(self.gen_params.isa.xlen * 2))
i2 = Signal(unsigned(self.gen_params.isa.xlen))
accepted = Signal(1, reset=1)
accepted = Signal(1, init=1)

@def_method(m, self.issue, ready=accepted)
def _(arg):
Expand Down
Loading

0 comments on commit 180232f

Please sign in to comment.