Skip to content

Commit

Permalink
Implement zicond (kuznia-rdzeni#747)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hazardu authored Nov 26, 2024
1 parent 240734d commit 061d287
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 11 deletions.
2 changes: 2 additions & 0 deletions coreblocks/arch/isa.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class Extension(enum.IntFlag):
ZICNTR = auto()
#: Enables hardware performance counters
ZIHPM = auto()
#: Integer conditional operations
ZICOND = auto()
#: Misaligned atomic operations
ZAM = auto()
#: Half precision floating-point operations (16-bit)
Expand Down
5 changes: 3 additions & 2 deletions coreblocks/arch/isa_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class Funct3(IntEnum, shape=3):
W = SLT = CSRRS = MULHSU = SH1ADD = CLMULR = _EBREAKPOINT = 0b010
D = SLTU = CSRRC = MULHU = CLMULH = _EINSTRPAGEFAULT = 0b011
BLT = BU = XOR = DIV = DIVW = SH2ADD = MIN = XNOR = ZEXTH = 0b100
BGE = HU = SR = CSRRWI = DIVU = DIVUW = BEXT = ORCB = REV8 = ROR = MINU = 0b101
BGE = HU = SR = CSRRWI = DIVU = DIVUW = BEXT = ORCB = REV8 = ROR = MINU = CZEROEQZ = 0b101
BLTU = OR = CSRRSI = REM = REMW = SH3ADD = MAX = ORN = 0b110
BGEU = AND = CSRRCI = REMU = REMUW = ANDN = MAXU = 0b111
BGEU = AND = CSRRCI = REMU = REMUW = ANDN = MAXU = CZERONEZ = 0b111


class Funct7(IntEnum, shape=7):
Expand All @@ -67,6 +67,7 @@ class Funct7(IntEnum, shape=7):
BINV = REV8 = 0b0110100
BSET = ORCB = 0b0010100
MAX = MIN = CLMUL = 0b0000101
CZERO = 0b0000111
ROL = ROR = SEXTB = SEXTH = CPOP = CLZ = CTZ = 0b0110000
ZEXTH = 0b0000100
SFENCEVMA = 0b0001001
Expand Down
4 changes: 4 additions & 0 deletions coreblocks/arch/optypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class OpType(IntEnum):
CLMUL = auto()
SRET = auto()
SFENCEVMA = auto()
CZERO = auto()
#: Internal Coreblocks OpType, specifing that instruction caused Exception before FU execution
EXCEPTION = auto()

Expand Down Expand Up @@ -154,6 +155,9 @@ def is_jalr(val: ValueLike) -> Value:
OpType.SRET,
OpType.SFENCEVMA,
],
Extension.ZICOND: [
OpType.CZERO,
],
}


Expand Down
4 changes: 4 additions & 0 deletions coreblocks/frontend/decoder/instr_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,8 @@ class Encoding:
Opcode.SYSTEM, Funct3.PRIV, Funct7.SFENCEVMA, rd_zero=True, instr_type_override=InstrType.R
), # sfence.vma
],
OpType.CZERO: [
Encoding(Opcode.OP, Funct3.CZEROEQZ, Funct7.CZERO),
Encoding(Opcode.OP, Funct3.CZERONEZ, Funct7.CZERO),
],
}
31 changes: 28 additions & 3 deletions coreblocks/func_blocks/fu/alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@


class AluFn(DecoderManager):
def __init__(self, zba_enable=False, zbb_enable=False) -> None:
def __init__(self, zba_enable=False, zbb_enable=False, zicond_enable=False) -> None:
self.zba_enable = zba_enable
self.zbb_enable = zbb_enable
self.zicond_enable = zicond_enable

class Fn(IntFlag):
ADD = auto() # Addition
Expand Down Expand Up @@ -60,6 +61,10 @@ class Fn(IntFlag):
ORCB = auto() # Bitwise or combine
REV8 = auto() # Reverse byte ordering

# ZICOND extension
CZEROEQZ = auto() # Move zero if condition if equal to zero
CZERONEZ = auto() # Move zero if condition is nonzero

def get_instructions(self) -> Sequence[tuple]:
return (
[
Expand Down Expand Up @@ -95,6 +100,11 @@ def get_instructions(self) -> Sequence[tuple]:
(self.Fn.CPOP, OpType.UNARY_BIT_MANIPULATION_5, Funct3.CPOP),
]
* self.zbb_enable
+ [
(self.Fn.CZEROEQZ, OpType.CZERO, Funct3.CZEROEQZ),
(self.Fn.CZERONEZ, OpType.CZERO, Funct3.CZERONEZ),
]
* self.zicond_enable
)


Expand All @@ -114,6 +124,7 @@ class Alu(Elaboratable):
def __init__(self, gen_params: GenParams, alu_fn=AluFn()):
self.zba_enable = alu_fn.zba_enable
self.zbb_enable = alu_fn.zbb_enable
self.zicond_enable = alu_fn.zicond_enable
self.gen_params = gen_params

self.fn = alu_fn.get_function()
Expand Down Expand Up @@ -206,6 +217,19 @@ def _or(s: Value) -> Value:
for i in range(en):
j = en - i - 1
m.d.comb += self.out[i * 8 : (i + 1) * 8].eq(self.in1[j * 8 : (j + 1) * 8])

if self.zicond_enable:
czero_cases = [
(AluFn.Fn.CZERONEZ, lambda is_zero: self.in1 if is_zero else 0),
(AluFn.Fn.CZEROEQZ, lambda is_zero: 0 if is_zero else self.in1),
]
for fn, output_fn in czero_cases:
with OneHotCase(fn):
with m.If(self.in2.any()):
m.d.comb += self.out.eq(output_fn(False))
with m.Else():
m.d.comb += self.out.eq(output_fn(True))

return m


Expand Down Expand Up @@ -254,10 +278,11 @@ def _(arg):


class ALUComponent(FunctionalComponentParams):
def __init__(self, zba_enable=False, zbb_enable=False):
def __init__(self, zba_enable=False, zbb_enable=False, zicond_enable=False):
self.zba_enable = zba_enable
self.zbb_enable = zbb_enable
self.alu_fn = AluFn(zba_enable=zba_enable, zbb_enable=zbb_enable)
self.zicond_enable = zicond_enable
self.alu_fn = AluFn(zba_enable=zba_enable, zbb_enable=zbb_enable, zicond_enable=zicond_enable)

def get_module(self, gen_params: GenParams) -> FuncUnit:
return AluFuncUnit(gen_params, self.alu_fn)
Expand Down
2 changes: 1 addition & 1 deletion coreblocks/params/configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def replace(self, **kwargs) -> Self:
func_units_config=(
RSBlockComponent(
[
ALUComponent(zba_enable=True, zbb_enable=True),
ALUComponent(zba_enable=True, zbb_enable=True, zicond_enable=True),
ShiftUnitComponent(zbb_enable=True),
ZbcComponent(),
ZbsComponent(),
Expand Down
18 changes: 17 additions & 1 deletion test/frontend/test_instr_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,24 @@ def __init__(
op=OpType.UNARY_BIT_MANIPULATION_1,
),
]
DECODER_TESTS_ZICOND = [
# CZERO RS2 RS1 EQZ RD OP
# nez 0b0000111 00000 00000 111 00000 0110011
# eqz 0b0000111 00000 00000 101 00000 0110011
# CZERO.NEZ
InstrTest(0x0E007033, Opcode.OP, Funct3.CZERONEZ, Funct7.CZERO, rd=0, rs1=0, rs2=0, op=OpType.CZERO),
# CZERO.EQZ
InstrTest(0x0E005033, Opcode.OP, Funct3.CZEROEQZ, Funct7.CZERO, rd=0, rs1=0, rs2=0, op=OpType.CZERO),
]

def setup_method(self):
self.gen_params = GenParams(
test_core_config.replace(
_implied_extensions=Extension.G | Extension.XINTMACHINEMODE | Extension.XINTSUPERVISOR | Extension.ZBB
_implied_extensions=Extension.G
| Extension.XINTMACHINEMODE
| Extension.XINTSUPERVISOR
| Extension.ZBB
| Extension.ZICOND
)
)
self.decoder = InstrDecoder(self.gen_params)
Expand Down Expand Up @@ -263,6 +276,9 @@ def test_xintsupervisor(self):
def test_zbb(self):
self.do_test(self.DECODER_TESTS_ZBB)

def test_zicond(self):
self.do_test(self.DECODER_TESTS_ZICOND)


class TestDecoderEExtLegal(TestCaseWithSimulator):
E_TEST = [
Expand Down
14 changes: 13 additions & 1 deletion test/func_blocks/fu/test_alu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class TestAluUnit(FunctionalUnitTestCase[AluFn.Fn]):
func_unit = ALUComponent(zba_enable=True, zbb_enable=True)
func_unit = ALUComponent(zba_enable=True, zbb_enable=True, zicond_enable=True)
zero_imm = False

ops = {
Expand Down Expand Up @@ -36,6 +36,8 @@ class TestAluUnit(FunctionalUnitTestCase[AluFn.Fn]):
AluFn.Fn.CLZ: ExecFn(OpType.UNARY_BIT_MANIPULATION_3, Funct3.CLZ),
AluFn.Fn.CTZ: ExecFn(OpType.UNARY_BIT_MANIPULATION_4, Funct3.CTZ),
AluFn.Fn.CPOP: ExecFn(OpType.UNARY_BIT_MANIPULATION_5, Funct3.CPOP),
AluFn.Fn.CZERONEZ: ExecFn(OpType.CZERO, Funct3.CZERONEZ, Funct7.CZERO),
AluFn.Fn.CZEROEQZ: ExecFn(OpType.CZERO, Funct3.CZEROEQZ, Funct7.CZERO),
}

@staticmethod
Expand Down Expand Up @@ -118,6 +120,16 @@ def compute_result(i1: int, i2: int, i_imm: int, pc: int, fn: AluFn.Fn, xlen: in
while (i1 & 1) == 0:
res += 1
i1 >>= 1
case AluFn.Fn.CZEROEQZ:
if i2 == 0:
res = 0
else:
res = i1
case AluFn.Fn.CZERONEZ:
if i2 == 0:
res = i1
else:
res = 0

return {"result": res & mask}

Expand Down
6 changes: 3 additions & 3 deletions test/params/test_configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class ISAStrTest:
),
ISAStrTest(
full_core_config,
"rv32imcbzicsr_zifencei_xintmachinemode",
"rv32imcbzicsr_zifencei_xintmachinemode",
"rv32imcbzicsr_zifencei_xintmachinemode",
"rv32imcbzicsr_zifencei_zicond_xintmachinemode",
"rv32imcbzicsr_zifencei_zicond_xintmachinemode",
"rv32imcbzicsr_zifencei_zicond_xintmachinemode",
),
ISAStrTest(tiny_core_config, "rv32e", "rv32e", "rv32e"),
ISAStrTest(test_core_config, "rv32", "rv32", "rv32i"),
Expand Down

0 comments on commit 061d287

Please sign in to comment.