*** Variables ***
&{mtvec_write_opcodes}                          0x10=0x30585073  0x11=0x3058d073  0x12=0x30595073  0x13=0x3059d073  0x14=0x305a5073
&{stvec_write_opcodes}                          0x10=0x10585073  0x11=0x1058d073  0x12=0x10595073  0x13=0x1059d073  0x14=0x105a5073

*** Keywords ***
Create Machine                                  
    [Arguments]                                 ${interrupt_mode}

    Execute Command                             using sysbus
    Execute Command                             mach create
    Execute Command                             machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV32 @ sysbus { cpuType: \\"rv32imac\\"; timeProvider: empty; privilegedArchitecture: PrivilegedArchitecture.Priv1_10; interruptMode: InterruptMode.${interruptMode} }"
    Execute Command                             machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x0 { size: 0x10000000 }"

    Execute Command                             cpu TbCacheEnabled false


MTVEC Should Be Equal
    [Arguments]                                 ${value}
    ${reg}=  Execute Command                    cpu MTVEC
    Should Be Equal                             ${reg.strip()}             ${value}


STVEC Should Be Equal
    [Arguments]                                 ${value}
    ${reg}=  Execute Command                    cpu STVEC
    Should Be Equal                             ${reg.strip()}             ${value}


Set MTVEC By Software
    [Arguments]                                 ${value}
    Execute Command                             cpu PC 0x0
    ${opcode}=  Get From Dictionary             ${mtvec_write_opcodes}  ${value}
    Execute Command                             sysbus WriteDoubleWord 0x0 ${opcode}
    Execute Command                             cpu Step

    # this is a hack giving time for the logger to handle all messages
    # (including the one generated by setting the MTVEC value)
    Sleep                                       1s


Set STVEC By Software
    [Arguments]                                 ${value}
    Execute Command                             cpu PC 0x0
    ${opcode}=  Get From Dictionary             ${stvec_write_opcodes}  ${value}
    Execute Command                             sysbus WriteDoubleWord 0x0 ${opcode}
    Execute Command                             cpu Step

    # this is a hack giving time for the logger to handle all messages
    # (including the one generated by setting the STVEC value)
    Sleep                                       1s
    
*** Test Cases ***
Should Correct MTVEC From Monitor in Auto Mode
    Create Log Tester                           0
    Create Machine                              Auto

    MTVEC Should Be Equal                       0x1010

    Execute Command                             cpu MTVEC 0x50
    MTVEC Should Be Equal                       0x50
    Should Not Be In Log                        modifying MTVEC

    Execute Command                             cpu MTVEC 0x51
    MTVEC Should Be Equal                       0x51
    Should Not Be In Log                        modifying MTVEC

    Execute Command                             cpu MTVEC 0x52
    MTVEC Should Be Equal                       0x50
    Wait For Log Entry                          modifying MTVEC

    Execute Command                             cpu MTVEC 0x53
    MTVEC Should Be Equal                       0x51
    Wait For Log Entry                          modifying MTVEC

    Execute Command                             cpu MTVEC 0x54
    MTVEC Should Be Equal                       0x54
    Should Not Be In Log                        modifying MTVEC


Should Correct STVEC From Monitor in Auto Mode
    Create Log Tester                           0
    Create Machine                              Auto

    STVEC Should Be Equal                       0x0

    Execute Command                             cpu STVEC 0x50
    STVEC Should Be Equal                       0x50
    Should Not Be In Log                        modifying STVEC

    Execute Command                             cpu STVEC 0x51
    STVEC Should Be Equal                       0x51
    Should Not Be In Log                        modifying STVEC

    Execute Command                             cpu STVEC 0x52
    STVEC Should Be Equal                       0x50
    Wait For Log Entry                          modifying STVEC

    Execute Command                             cpu STVEC 0x53
    STVEC Should Be Equal                       0x51
    Wait For Log Entry                          modifying STVEC

    Execute Command                             cpu STVEC 0x54
    STVEC Should Be Equal                       0x54
    Should Not Be In Log                        modifying STVEC


Should Correct MTVEC Written By Software in Auto Mode
    Create Log Tester                           0
    Create Machine                              Auto

    MTVEC Should Be Equal                       0x1010

    Set MTVEC By Software                       0x10
    MTVEC Should Be Equal                       0x10
    Should Not Be In Log                        MTVEC value written to CSR corrected

    Set MTVEC By Software                       0x11
    MTVEC Should Be Equal                       0x11
    Should Not Be In Log                        MTVEC value written to CSR corrected

    Set MTVEC By Software                       0x12
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x10

    Set MTVEC By Software                       0x13
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x11

    Set MTVEC By Software                       0x14
    MTVEC Should Be Equal                       0x14
    Should Not Be In Log                        MTVEC value written to CSR corrected


Should Correct STVEC Written By Software in Auto Mode
    Create Log Tester                           0
    Create Machine                              Auto

    STVEC Should Be Equal                       0x0

    Set STVEC By Software                       0x10
    STVEC Should Be Equal                       0x10
    Should Not Be In Log                        STVEC value written to CSR corrected

    Set STVEC By Software                       0x11
    STVEC Should Be Equal                       0x11
    Should Not Be In Log                        STVEC value written to CSR corrected

    Set STVEC By Software                       0x12
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x10

    Set STVEC By Software                       0x13
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x11

    Set STVEC By Software                       0x14
    STVEC Should Be Equal                       0x14
    Should Not Be In Log                        STVEC value written to CSR corrected


Should Correct MTVEC From Monitor in Direct Mode
    Create Log Tester                           0
    Create Machine                              Direct

    MTVEC Should Be Equal                       0x1010

    Execute Command                             cpu MTVEC 0x50
    MTVEC Should Be Equal                       0x50
    Should Not Be In Log                        modifying MTVEC

    Execute Command                             cpu MTVEC 0x51
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x50

    Execute Command                             cpu MTVEC 0x52
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x50

    Execute Command                             cpu MTVEC 0x53
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x50

    Execute Command                             cpu MTVEC 0x54
    MTVEC Should Be Equal                       0x54
    Should Not Be In Log                        modifying MTVEC


Should Correct STVEC From Monitor in Direct Mode
    Create Log Tester                           0
    Create Machine                              Direct

    STVEC Should Be Equal                       0x0

    Execute Command                             cpu STVEC 0x50
    STVEC Should Be Equal                       0x50
    Should Not Be In Log                        modifying STVEC

    Execute Command                             cpu STVEC 0x51
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x50

    Execute Command                             cpu STVEC 0x52
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x50

    Execute Command                             cpu STVEC 0x53
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x50

    Execute Command                             cpu STVEC 0x54
    STVEC Should Be Equal                       0x54
    Should Not Be In Log                        modifying STVEC


Should Correct MTVEC Written By Software in Direct Mode
    Create Log Tester                           0
    Create Machine                              Direct

    MTVEC Should Be Equal                       0x1010

    Set MTVEC By Software                       0x10
    MTVEC Should Be Equal                       0x10
    Should Not Be In Log                        MTVEC value written to CSR corrected

    Set MTVEC By Software                       0x11
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x10

    Set MTVEC By Software                       0x12
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x10

    Set MTVEC By Software                       0x13
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x10

    Set MTVEC By Software                       0x14
    MTVEC Should Be Equal                       0x14
    Should Not Be In Log                        MTVEC value written to CSR corrected


Should Correct STVEC Written By Software in Direct Mode
    Create Log Tester                           0
    Create Machine                              Direct

    STVEC Should Be Equal                       0x0

    Set STVEC By Software                       0x10
    STVEC Should Be Equal                       0x10
    Should Not Be In Log                        STVEC value written to CSR corrected

    Set STVEC By Software                       0x11
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x10

    Set STVEC By Software                       0x12
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x10

    Set STVEC By Software                       0x13
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x10

    Set STVEC By Software                       0x14
    STVEC Should Be Equal                       0x14
    Should Not Be In Log                        STVEC value written to CSR corrected


Should Correct MTVEC From Monitor in Vectored Mode
    Create Log Tester                           0
    Create Machine                              Vectored

    Wait For Log Entry                          Vectored interrupt mode set - updating MTVEC
    MTVEC Should Be Equal                       0x1011

    Execute Command                             cpu MTVEC 0x50
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x51

    Execute Command                             cpu MTVEC 0x51
    MTVEC Should Be Equal                       0x51
    Should Not Be In Log                        modifying MTVEC

    Execute Command                             cpu MTVEC 0x52
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x51

    Execute Command                             cpu MTVEC 0x53
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x51

    Execute Command                             cpu MTVEC 0x54
    Wait For Log Entry                          modifying MTVEC
    MTVEC Should Be Equal                       0x55


Should Correct STVEC From Monitor in Vectored Mode
    Create Log Tester                           0
    Create Machine                              Vectored

    Wait For Log Entry                          Vectored interrupt mode set - updating STVEC
    STVEC Should Be Equal                       0x1

    Execute Command                             cpu STVEC 0x50
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x51

    Execute Command                             cpu STVEC 0x51
    STVEC Should Be Equal                       0x51
    Should Not Be In Log                        modifying STVEC

    Execute Command                             cpu STVEC 0x52
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x51

    Execute Command                             cpu STVEC 0x53
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x51

    Execute Command                             cpu STVEC 0x54
    Wait For Log Entry                          modifying STVEC
    STVEC Should Be Equal                       0x55


Should Correct MTVEC Written By Software in Vectored Mode
    Create Log Tester                           0
    Create Machine                              Vectored

    MTVEC Should Be Equal                       0x1011

    Set MTVEC By Software                       0x10
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x11

    Set MTVEC By Software                       0x11
    MTVEC Should Be Equal                       0x11
    Should Not Be In Log                        MTVEC value written to CSR corrected

    Set MTVEC By Software                       0x12
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x11

    Set MTVEC By Software                       0x13
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x11

    Set MTVEC By Software                       0x14
    Wait For Log Entry                          MTVEC value written to CSR corrected
    MTVEC Should Be Equal                       0x15


Should Correct STVEC Written By Software in Vectored Mode
    Create Log Tester                           0
    Create Machine                              Vectored

    STVEC Should Be Equal                       0x1

    Set STVEC By Software                       0x10
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x11

    Set STVEC By Software                       0x11
    STVEC Should Be Equal                       0x11
    Should Not Be In Log                        STVEC value written to CSR corrected

    Set STVEC By Software                       0x12
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x11

    Set STVEC By Software                       0x13
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x11

    Set STVEC By Software                       0x14
    Wait For Log Entry                          STVEC value written to CSR corrected
    STVEC Should Be Equal                       0x15
