{-# LANGUAGE DataKinds #-} {-# LANGUAGE NumericUnderscores #-} module Read(Read.read) where import DecodeTypes( Opcode(..), RTypeFields(..), ITypeFields(..), STypeFields(..), BTypeFields(..), UTypeFields(..), JTypeFields(..), ) import Clash.Prelude import Decode(DecodeResult(..)) import Cpu(RISCVCPU(..)) import RegFiles (RegVal(..), GPR) read :: DecodeResult -> RISCVCPU -> DecodeResult read (Opcode opc) riscvCPU = let gprRegFile = gpr riscvCPU in case opc of -- R-Type ADD fields -> Opcode (ADD (readRTypeFields fields gprRegFile)) SUB fields -> Opcode (SUB (readRTypeFields fields gprRegFile)) XOR fields -> Opcode (XOR (readRTypeFields fields gprRegFile)) OR fields -> Opcode (OR (readRTypeFields fields gprRegFile)) AND fields -> Opcode (AND (readRTypeFields fields gprRegFile)) SLL fields -> Opcode (SLL (readRTypeFields fields gprRegFile)) SRL fields -> Opcode (SRL (readRTypeFields fields gprRegFile)) SRA fields -> Opcode (SRA (readRTypeFields fields gprRegFile)) SLT fields -> Opcode (SLT (readRTypeFields fields gprRegFile)) SLTU fields -> Opcode (SLTU (readRTypeFields fields gprRegFile)) -- I-Type ADDI fields -> Opcode (ADDI (readITypeFields fields gprRegFile)) XORI fields -> Opcode (XORI (readITypeFields fields gprRegFile)) ORI fields -> Opcode (ORI (readITypeFields fields gprRegFile)) ANDI fields -> Opcode (ANDI (readITypeFields fields gprRegFile)) SLLI fields -> Opcode (SLLI (readITypeFields fields gprRegFile)) SRLI fields -> Opcode (SRLI (readITypeFields fields gprRegFile)) SRAI fields -> Opcode (SRAI (readITypeFields fields gprRegFile)) SLTI fields -> Opcode (SLTI (readITypeFields fields gprRegFile)) SLTIU fields -> Opcode (SLTIU (readITypeFields fields gprRegFile)) LB fields -> Opcode (LB (readITypeFields fields gprRegFile)) LH fields -> Opcode (LH (readITypeFields fields gprRegFile)) LW fields -> Opcode (LW (readITypeFields fields gprRegFile)) LBU fields -> Opcode (LBU (readITypeFields fields gprRegFile)) LHU fields -> Opcode (LHU (readITypeFields fields gprRegFile)) JALR fields -> Opcode (JALR (readITypeFields fields gprRegFile)) ECALL fields -> Opcode (ECALL (readITypeFields fields gprRegFile)) -- No regs needed, but consistent EBREAK fields -> Opcode (EBREAK (readITypeFields fields gprRegFile)) -- Ditto -- S-Type SB fields -> Opcode (SB (readSTypeFields fields gprRegFile)) SH fields -> Opcode (SH (readSTypeFields fields gprRegFile)) SW fields -> Opcode (SW (readSTypeFields fields gprRegFile)) -- B-Type BEQ fields -> Opcode (BEQ (readBTypeFields fields gprRegFile)) BNE fields -> Opcode (BNE (readBTypeFields fields gprRegFile)) BLT fields -> Opcode (BLT (readBTypeFields fields gprRegFile)) BGE fields -> Opcode (BGE (readBTypeFields fields gprRegFile)) BLTU fields -> Opcode (BLTU (readBTypeFields fields gprRegFile)) BGEU fields -> Opcode (BGEU (readBTypeFields fields gprRegFile)) -- U-Type LUI fields -> Opcode (LUI (readUTypeFields fields gprRegFile)) AUIPC fields -> Opcode (AUIPC (readUTypeFields fields gprRegFile)) -- J-Type JAL fields -> Opcode (JAL (readJTypeFields fields gprRegFile)) read (DecodeException e) _ = DecodeException e read (InstructionException e) _ = InstructionException e readRTypeFields :: RTypeFields -> GPR -> RTypeFields readRTypeFields (RTypeFields rd funct3 rs1 rs2 funct7) gprRegFile = let rs1_val = fetchGPRRegVal rs1 gprRegFile rs2_val = fetchGPRRegVal rs2 gprRegFile in RTypeFields rd funct3 rs1_val rs2_val funct7 readITypeFields :: ITypeFields -> GPR -> ITypeFields readITypeFields (ITypeFields rd funct3 rs1 imm) gprRegFile = let rs1_val = fetchGPRRegVal rs1 gprRegFile in ITypeFields rd funct3 rs1_val imm readSTypeFields :: STypeFields -> GPR -> STypeFields readSTypeFields (STypeFields funct3 rs1 rs2 imm12) gprRegFile = let rs1_val = fetchGPRRegVal rs1 gprRegFile rs2_val = fetchGPRRegVal rs2 gprRegFile in STypeFields funct3 rs1_val rs2_val imm12 readBTypeFields :: BTypeFields -> GPR -> BTypeFields readBTypeFields (BTypeFields funct3 rs1 rs2 imm13) gprRegFile = let rs1_val = fetchGPRRegVal rs1 gprRegFile rs2_val = fetchGPRRegVal rs2 gprRegFile in BTypeFields funct3 rs1_val rs2_val imm13 readUTypeFields :: UTypeFields -> GPR -> UTypeFields readUTypeFields fields@(UTypeFields rd imm20) _ = fields readJTypeFields :: JTypeFields -> GPR -> JTypeFields readJTypeFields fields@(JTypeFields rd imm21) _ = fields fetchGPRRegVal :: RegVal -> GPR -> RegVal fetchGPRRegVal (Unpopulated idx) gprVal = Value idx (gprVal !! idx) fetchGPRRegVal val@(Value _ _) _ = val -- Already populated, no change