/ coreblocks / func_blocks / fu / common / fu_decoder.py
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)