#########################################################################################
# GR716B-GRSCRUB Application Note
#
# User-case scenario demonstration of the FPGA supervisor (GRSCRUB) capabilities on the GR716B rad-hard microcontroller.
# Overview:  The demo shows how to program and scrub the FPGA using the GR716B microcontroller. Errors are injected into the FPGA configuration 
# memory (CRAM) to simulate radiation-induced upsets. After each error injection, a scrubbing cycle is executed to correct the error.
#
# This readme file is for reference only and all required information is provided in the Application Note document.
#
# Author: Adria Barros de Oliveira - Frontgrade Gaisler AB
# Edited: 30/10/2024
#
#########################################################################################


### NOTES

- The Setup I is composed of: GR716B board, XC6S board (TC), and GR-CPCIS-XCKU060 (target AMD/Xilinx Kintex UltraScale XCKU060).
- The Setup II is composed of: GR-CPCIS-XCKU060 rev. 2.1 board featuring a GR716B microcontroller and an AMD/Xilinx Kintex UltraScale XCKU060 FPGA
- The setups overview is presented in the Application Note document.
- The current version of the test setup targets the KU060 FPGA.
- Error injection in some CRAM bits might also trigger other bits to flip. In that case, GRSCRUB will detect multiple errors for the injected bit-flip.
- It is not possible to detect errors injected in masked bits.
- Sequential error injection in the same frame without correction in between will lead GRSCRUB to report only errors in the first faulty word. 
This occurs because GRSCRUB in readback FFC mode fixes the entire frame at the first faulty word detected, and the other words are not checked.


### TOOLS

- Python 2.7 (only for Setup I)
- GRMON4


### SCRIPTS

- Different set of scripts are available:
--> scripts_misc: genneral support scripts.
--> scripts_eifw: scripts used for GRSCRUB validation with error injection.


### LOGS

- logs/subrunX/log_gr716b_grmon_<timestamp>.log: grmon output log

- logs/subrunX/log_gr716b_eictrl_<timestamp>.log: TCL scripts main log
    This log shows the error injection and GR716B/GRSCRUB configuration.

- logs/log_ei_data_<timestamp>.log: error injection data log
    This log shows all injected errors in the target FPGA CRAM.
    Columns description:
        FI id: error injection id set by the fpga_ctrl.tcl (injection execution)
        Fault number: error injection number 
            This value will be #1 if only one error is configured to be injected at the execution.
            If n errors are configured to be injected at the execution, this number will be from #1 to #n.
        Frame id: Id of the CRAM affected frame
        Frame addr: Address of the CRAM affected frame
        Bit pos: Bit position that is flipped in the frame
        FI result: Result of the error injection (only for SETUP I)
            S -> successful injection
            X -> could not inject, in this case a new injection occurs in different position


### INITIAL CONFIGURATION

#1 - Save the user defined KU060 bit, mask, and CRC data inside the DUT folder (optional).
    Load all required data to the SPI on the GR716B board (mandatory).

#2 - Configure the scripts

    Primary user configurations:
        - Configure the memory addresses and user defined variables in scripts_eifw/grscrub_ctrl.tcl script.
        - Configure UART parameters in scripts_eifw/fpgaei_campaign.py script (if using SETUP I).

    Other elements in the scripts shall be configured as needed. 
    
    Table below describes the file, variables, and what requires mandatory user configuration.

    | FILE                            | VARIABLE              | COMMENT
    | scripts_eifw/grscrub_ctrl.tcl   | COMP_MEMADDR          | Golden memory base address
    | scripts_eifw/grscrub_ctrl.tcl   | BITPARAMS(LOADAD.XXX) | Golden memory address
    | scripts_eifw/fpgaei_campaign.py | port_inj              | serial port (if using SETUP I)

#3 - GRMON connection

#3.1 - Configure PLL - SYSCLK=50MHz

    - Run the run_pll_fix.sh. It needs to be executed only after a reset/power cycle.
      Note that, on the GR-CPCIS-XCKU060, the GR716B UART is the second on the FTDI (hereafter reffered as <GR716B-DSU-UART>).
    
    Type: 
       ./run_pll_fix <GR716B-DSU-UART>

#3.2 - Run the demo scripts
    - Run run_ctrl_ei.sh. run_ctrl_ei.sh is a bash script that already calls grmon4, loads the test scripts, and starts logging.
      One should update the grmon path and debug link in run_ctrl_ei.sh if needed.

    Type:
        sh run_ctrl_ei.sh <GR716B-DSU-UART> <RUN-ID>


### EXECUTION STEPS - SETUP I

#4 - Execution on GRMON4

#4.1 - Initial configuration
    - Set logs
    - GRSCRUB config
    - FPGA programming

    Type:
        grmon4> gr init <RUN-ID>
        grmon4> ei config

#4.2 - Run error injection example (with correction)
    - Random injection
    - GRSCRUB readback mode
        <readback_correction_type> can be "ffc" (FFC only), "crc" (CRC only), "all" (FFC+CRC) 

    Type:
        grmon4> ei run <number_of_executions> <number_of_errors_per_execution> <readback_correction_type>

    Ex:
        grmon4> ei run 100 1 all

# 4.3 - Run your own error injection (without correction)

    For random injections type: 
        grmon4> ei rand <execution_id> <number_of_errors_per_execution>

    For deterministic injections type: 
        grmon4> ei det <execution_id> <number_of_errors_per_execution> <fpga_frame_id> <bit_position>


### EXECUTION STEPS - SETUP II (GR-CPCIS-XCKU060 rev. 2.1 board)

#4 - Execution on GRMON4

#4.1 - Initial configuration
    - Set logs
    - GRSCRUB config

    Type:
        grmon4> gr init <RUN-ID>

#4.2 - Run error injection example (with correction)
    - Performs FPGA programming first. The DONE LED on the board front panel lights up.
    - The default example is a random injection combined with GRSCRUB readback FFC+CRC. 
    - Note that programming the FPGA takes about 26 seconds and each injection execution takes about 36 seconds.
    
    Type:
        grmon4> ei run <number_of_executions>

    Ex:
        grmon4> ei run 5

    
    It can be updated depending on the configuration below.
    
    Type:
        grmon4> ei run <number_of_executions> <number_of_errors_per_execution> <scrub_type> <readback_correction_type>

        Where:
        <number_of_executions>: number of executions of the error injection campaign
        <number_of_errors_per_execution> number of errors injected per execution (currently only one fault is injected at once). This value must be 1 for now.
        <scrub_type> scrubbing mode. It can be "rdbk" for readback (default), otherwise blind scrubbing is enabled.
        <readback_correction_type>: for GRSCRUB readback mode only. It can be "ffc" (FFC only), "crc" (CRC only), "all" (FFC+CRC) 

    Ex: Readback 100 executions with all detection modes (FFC+CRC) enabled
        grmon4> ei run 100 1 rdbk all

    Ex: Readback 30 executions with FFC detection mode enabled
        grmon4> ei run 30 1 rdbk ffc

    Ex: Readback 2 executions with CRC detection mode enabled
        grmon4> ei run 2 1 rdbk crc

    Ex: Blind scrubbin 5 executions
        grmon4> ei run 5 1 blind

5 - Exit GRMON4
        <scrub_type> scrubbing mode. It can be "rdbk" for readback (default), otherwise blind scrubbing is enabled.
        <readback_correction_type>: for GRSCRUB readback mode only. It can be "ffc" (FFC only), "crc" (CRC only), "all" (FFC+CRC) 

    Ex:
        grmon4> ei run 100 1 rdbk all




