diff --git a/hs/Execute.hs b/hs/Execute.hs index 2694391..020311c 100644 --- a/hs/Execute.hs +++ b/hs/Execute.hs @@ -5,19 +5,208 @@ module Execute(execute) where import Clash.Prelude import Decode(DecodeResult(..)) -import DecodeTypes(Opcode(..)) - +import DecodeTypes( + Opcode(..), + RTypeFields(..), ITypeFields(..), STypeFields(..), + BTypeFields(..), UTypeFields(..), JTypeFields(..) + ) import Types(Addr, DoubleWord) +import Exceptions(Exception(..)) import BusTypes( WriteRequest(..), ReadRequest(..), + TransactionSize(..), + BusVal(..) ) -import RegFiles(RegFileIdx) +import RegFiles(RegFileIdx, RegVal(..)) import Util((|>)) data ExecuteResult = ReadRequest {readRequest :: ReadRequest, insnAddr :: Addr} | WriteRequest {writeRequest :: WriteRequest, insnAddr :: Addr} | WriteBackGPR {idx :: RegFileIdx, val :: DoubleWord} + | Jump { targetAddr :: Addr } + | DecodeException {exception :: Exception, insnAddr :: Addr} + | InstructionException {exception :: Exception, insnAddr :: Addr} + deriving (Generic, Show, Eq, NFDataX) +-- Helper functions to extract values from RegVal +extractRegVal :: RegVal -> DoubleWord +extractRegVal (Value _ val) = val +extractRegVal (Unpopulated _) = undefined + +-- Execute function execute :: DecodeResult -> ExecuteResult -execute = undefined \ No newline at end of file +execute (Opcode opcode addr) = case opcode of + -- R-Type Instructions + ADD (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 + val2) + SUB (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 - val2) + XOR (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 `xor` val2) + OR (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 .|. val2) + AND (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 .&. val2) + SLL (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 `shiftL` fromIntegral (val2 .&. 0x3F)) + SRL (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (val1 `shiftR` fromIntegral (val2 .&. 0x3F)) + SRA (RTypeFields rd _ rs1 rs2 _) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + val2 = extractRegVal rs2 + in WriteBackGPR rd (bitCoerce (val1 `shiftR` fromIntegral (val2 .&. 0x3F))) + SLT (RTypeFields rd _ rs1 rs2 _) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64 + in WriteBackGPR rd (if val1 < val2 then 1 else 0) + SLTU (RTypeFields rd _ rs1 rs2 _) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + in WriteBackGPR rd (if val1 < val2 then 1 else 0) + + -- I-Type Instructions + ADDI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + immVal = signExtend imm + in WriteBackGPR rd (val1 + immVal) + XORI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + immVal = signExtend imm + in WriteBackGPR rd (val1 `xor` immVal) + ORI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + immVal = signExtend imm + in WriteBackGPR rd (val1 .|. immVal) + ANDI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + immVal = signExtend imm + in WriteBackGPR rd (val1 .&. immVal) + SLLI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + shamt = imm .&. 0x3F + in WriteBackGPR rd (val1 `shiftL` fromIntegral shamt) + SRLI (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + shamt = imm .&. 0x3F + in WriteBackGPR rd (val1 `shiftR` fromIntegral shamt) + SRAI (ITypeFields rd _ rs1 imm) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + shamt = imm .&. 0x3F + in WriteBackGPR rd (bitCoerce (val1 `shiftR` fromIntegral shamt)) + SLTI (ITypeFields rd _ rs1 imm) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + immVal = unpack (pack (signExtend imm) :: BitVector 64) :: Signed 64 + in WriteBackGPR rd (if val1 < immVal then 1 else 0) + SLTIU (ITypeFields rd _ rs1 imm) -> + let val1 = extractRegVal rs1 + immVal = signExtend imm + in WriteBackGPR rd (if val1 < immVal then 1 else 0) + LB (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeByte) addr + LH (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeHalfWord) addr + LW (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeFullWord) addr + LBU (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeByte) addr + LHU (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + in Execute.ReadRequest (BusTypes.ReadRequest (baseAddr + offset) SizeHalfWord) addr + JALR (ITypeFields rd _ rs1 imm) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm + target = baseAddr + offset + in if rd /= 0 then WriteBackGPR rd (addr + 4) else Jump target + ECALL (ITypeFields _ _ _ _) -> + Execute.DecodeException EnvironmentCallFromMMode addr -- Assuming Machine mode for now + EBREAK (ITypeFields _ _ _ _) -> + Execute.DecodeException Breakpoint addr + + -- S-Type Instructions + SB (STypeFields _ rs1 rs2 imm12) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm12 + val = extractRegVal rs2 + in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusByte (resize val))) addr + SH (STypeFields _ rs1 rs2 imm12) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm12 + val = extractRegVal rs2 + in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusHalfWord (resize val))) addr + SW (STypeFields _ rs1 rs2 imm12) -> + let baseAddr = extractRegVal rs1 + offset = signExtend imm12 + val = extractRegVal rs2 + in Execute.WriteRequest (BusTypes.WriteRequest (baseAddr + offset) (BusFullWord (resize val))) addr + + -- B-Type Instructions + BEQ (BTypeFields _ rs1 rs2 imm13) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + offset = signExtend imm13 + in if val1 == val2 then Jump (addr + offset) else Jump (addr + 4) + BNE (BTypeFields _ rs1 rs2 imm13) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + offset = signExtend imm13 + in if val1 /= val2 then Jump (addr + offset) else Jump (addr + 4) + BLT (BTypeFields _ rs1 rs2 imm13) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64 + offset = signExtend imm13 + in if val1 < val2 then Jump (addr + offset) else Jump (addr + 4) + BGE (BTypeFields _ rs1 rs2 imm13) -> + let val1 = unpack (pack (extractRegVal rs1) :: BitVector 64) :: Signed 64 + val2 = unpack (pack (extractRegVal rs2) :: BitVector 64) :: Signed 64 + offset = signExtend imm13 + in if val1 >= val2 then Jump (addr + offset) else Jump (addr + 4) + BLTU (BTypeFields _ rs1 rs2 imm13) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + offset = signExtend imm13 + in if val1 < val2 then Jump (addr + offset) else Jump (addr + 4) + BGEU (BTypeFields _ rs1 rs2 imm13) -> + let val1 = extractRegVal rs1 + val2 = extractRegVal rs2 + offset = signExtend imm13 + in if val1 >= val2 then Jump (addr + offset) else Jump (addr + 4) + + -- U-Type Instructions + LUI (UTypeFields rd imm20) -> + let val = shiftL (resize imm20) 12 + in WriteBackGPR rd val + AUIPC (UTypeFields rd imm20) -> + let val = addr + shiftL (resize imm20) 12 + in WriteBackGPR rd val + + -- J-Type Instructions + JAL (JTypeFields rd imm21) -> + let offset = signExtend imm21 + in if rd /= 0 then WriteBackGPR rd (addr + 4) else Jump (addr + offset) + +execute (Decode.DecodeException e addr) = Execute.DecodeException e addr +execute (Decode.InstructionException e addr) = Execute.InstructionException e addr \ No newline at end of file