if { [info exists CHIPNAME] } {
   set  _CHIPNAME $CHIPNAME
} else {
   set  _CHIPNAME riscv
}

jtag newtap $_CHIPNAME tap -irlen 5
set _TARGETNAME $_CHIPNAME.tap
target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -rtos hwthread

# Configure work area in on-chip SRAM
$_TARGETNAME.0 configure -work-area-phys 0x50001000 -work-area-size 0x1000 -work-area-backup 0

$_TARGETNAME.0 configure -event gdb-detach {
    resume
}

$_TARGETNAME.0 riscv expose_csrs 1968=dcsr
$_TARGETNAME.0 riscv expose_csrs 1969=dpc
$_TARGETNAME.0 riscv expose_csrs 1988=dmst
$_TARGETNAME.0 riscv expose_csrs 1992=dicawics
$_TARGETNAME.0 riscv expose_csrs 1996=dicad0h
$_TARGETNAME.0 riscv expose_csrs 1993=dicad0
$_TARGETNAME.0 riscv expose_csrs 1994=dicad1
$_TARGETNAME.0 riscv expose_csrs 1995=dicago

proc write_icache_line {dicawics_ dicad0_ dicad0h_ dicad1_} {
    # 1. Write dicawics
    reg csr_dicawics $dicawics_
    # 2. Write instruction data to dicad0 and dicad0h, and parity to dicad1
    reg csr_dicad0 $dicad0_
    reg csr_dicad0h $dicad0h_
    reg csr_dicad1 $dicad1_
    # 3. Write 1 to dicago to trigger Icache write operation
    reg csr_dicago 1
}

proc read_icache_line {dicawics_} {
    # 1. Write dicawics
    reg csr_dicawics $dicawics_
    # 2. Read to dicago to trigger Icache read operation
    reg csr_dicago
    # 3. get line chunk from dicad0 and dicad0h, and parity from dicad1
    reg csr_dicad0
    reg csr_dicad0h
    reg csr_dicad1
}

proc write_icache_tag {dicawics_ dicad0_ dicad1_} {
    # 1. Write dicawics
    reg csr_dicawics $dicawics_
    # 2. Write tag, valid, LRU information to dicad0, and parity to dicad1
    reg csr_dicad0 $dicad0_
    reg csr_dicad1 $dicad1_
    # 3. Write 1 to dicago to trigger Icache write operation
    reg csr_dicago 1
}

proc read_icache_tag {dicawics_} {
    # 1. Write dicawics
    reg csr_dicawics $dicawics_
    # 2. Read to dicago to trigger Icache read operation
    reg csr_dicago
    # 3. get tag from dicad0, and parity from dicad1
    reg csr_dicad0
    reg csr_dicad1
}

$_TARGETNAME.0 configure -event halted {
    echo "Starting ICache line read"
    # dicawics: array=0 way=1 index=1
    set dicawics_value [expr {(0 << 24) | (1 << 20) | (1 << 5)}]
    read_icache_line $dicawics_value

    echo "Starting ICache line write"
    # Write instruction data to dicad0 and dicad0h
    set dicad0_value 0x30c00
    set dicad0h_value 0xc00c0
    # Write wrong parity to trigger error
    set dicad1_value 0xffffaaaa
    # iterate to perform write for many values of index
    for {set index 0} {$index < 5} {incr index} {
        # dicawics: array=0 way=1
        set dicawics_value [expr {(0 << 24) | (1 << 20) | ($index << 5)}]
        write_icache_line $dicawics_value $dicad0_value $dicad0h_value $dicad1_value
    }

    echo "Starting ICache tag and status read"
    read_icache_tag $dicawics_value

    echo "Starting ICache tag and status write"
    # Write tag, valid, LRU information are in dicad0, parity is in dicad1
    set dicad0_value 0xfcb
    set dicad1_value 0xffffffff
    for {set index 0} {$index < 5} {incr index} {
    # dicawics: array=1 way=1
    set dicawics_value [expr {(1 << 24) | (1 << 20) | ($index << 5)}]
    write_icache_tag $dicawics_value $dicad0_value $dicad1_value
    }
    echo "ICache test done."
}

# Mem access mode
riscv set_mem_access abstract

# Be verbose about GDB errors
gdb_report_data_abort enable
gdb_report_register_access_error enable

# Always use hardware breakpoints.
gdb_breakpoint_override hard
