fu_decoder.py
1 from typing import Sequence, Type 2 from amaranth import * 3 4 from coreblocks.params import GenParams 5 from coreblocks.interface.layouts import CommonLayoutFields 6 7 from enum import IntFlag 8 9 from coreblocks.arch.optypes import OpType 10 11 12 __all__ = ["Decoder", "DecoderManager"] 13 14 15 class Decoder(Elaboratable): 16 """ 17 Module responsible for instruction decoding. 18 19 Attributes 20 ---------- 21 decode_fn: Signal 22 exec_fn: View 23 """ 24 25 def __init__(self, gen_params: GenParams, decode_fn: Type[IntFlag], ops: Sequence[tuple], check_optype: bool): 26 layouts = gen_params.get(CommonLayoutFields) 27 28 self.exec_fn = Signal(layouts.exec_fn_layout) 29 self.decode_fn = Signal(decode_fn) 30 self.ops = ops 31 self.check_optype = check_optype 32 33 def elaborate(self, platform): 34 m = Module() 35 36 for op in self.ops: 37 optype_match = self.exec_fn.op_type == op[1] if self.check_optype else 1 38 funct3_match = self.exec_fn.funct3 == op[2] if len(op) >= 3 else 1 39 funct7_match = self.exec_fn.funct7 == op[3] if len(op) >= 4 else 1 40 41 cond = optype_match & funct3_match & funct7_match 42 43 assert op # for typing, TODO: better typing 44 signal_num = op[0].bit_length() - 1 45 46 m.d.comb += self.decode_fn[signal_num].eq(cond) 47 48 return m 49 50 51 class DecoderManager: 52 """Class responsible for instruction management.""" 53 54 Fn: Type[IntFlag] 55 """Enumeration of instructions implemented in given functional unit.""" 56 57 def get_instructions(self) -> Sequence[tuple]: 58 """Method providing list of valid instruction. 59 60 Returns 61 ------- 62 return : Sequence[tuple] 63 List of implemented instructions, each following format: 64 (IntFlag, OpType, Funct3 (optional), Funct7 (optional)) 65 66 """ 67 raise NotImplementedError 68 69 def get_op_types(self) -> set[OpType]: 70 """Method returning op types from listed instructions. 71 72 Returns 73 ------- 74 return : set[OpType] 75 List of OpTypes. 76 """ 77 return {instr[1] for instr in self.get_instructions()} 78 79 def get_decoder(self, gen_params: GenParams) -> Decoder: 80 """Method returning auto generated instruction decoder. 81 82 Parameters 83 ---------- 84 gen_params: GenParams 85 Generation parameters passed to a decoder contructor. 86 87 Returns 88 ------- 89 return : Decoder 90 Instance of Decoder class. 91 """ 92 # check how many different op types are there 93 op_types = self.get_op_types() 94 multiple_op_types = len(op_types) > 1 95 96 # if multiple op types detected, request op_type check in decoder 97 return Decoder(gen_params, self.Fn, self.get_instructions(), check_optype=multiple_op_types) 98 99 def get_function(self) -> Value: 100 """Method returning Signal Object for decoder, called function in FU blocks 101 102 Returns 103 ------- 104 return : Value 105 Signal object. 106 """ 107 return Signal(self.Fn)