1. About the Nios® V Processor Lockstep
2. Overview
3. Controlling the Nios® V Processor Lockstep
4. Programming Model
5. Signals, Interfaces, and Build Parameters
6. Using Nios® V Processor Lock Step
A. Document Revision History for the Nios® V Processor: Lockstep Implementation User Guide
B. Appendix
4.4.1. CPUs’ Reset Control Register - DCLSM_CPURC
4.4.2. DCLSM Basic Control Register - DCLSM_CTRL
4.4.3. DCLSM Blind Window Control Register - DCLSM_BWCR
4.4.4. All Alarms’ Prior Alarms’ Fault Injection Register - ERRCTRL_ALL_ALARMS_PRIOR_AFI
4.4.5. INTREQ Configuration Register - ERRCTRL_INTREQ_CONF
4.4.6. Timeout Deadline and Status Register - ERRCTRL_TIMEOUT
4.4.7. Timeout Acknowledgment Register - ERRCTRL_TIMEOUT_ACK
4.4.8. Enable Key fRSmartComp Control Register - ERRCTRL_ENABLE_KEY
4.4.9. Root Fault Injection Control register - ERRCTRL_ROOT_INJ
4.4.10. Alarm Fault Injection Control register - ERRCTRL_ALARM_INJ
4.4.11. Event Mask Configuration register - ERRCTRL_MASKA and ERRCTRL_MASKB
4.4.12. Alarm Routing Configuration register - ERRCTRL_ROUTA and ERRCTRL_ROUTB
4.4.13. Error Controller PGO LOG Reset Control register - ERRCTRL_PGOLOGRST
4.4.14. PGO0 and PGO4 Configuration registers - ERRCTRL_PGO0 and ERRCTRL_PGO4
4.4.15. FN_MODEIN Control Register - ERRCTRL_FNMODEIN
4.4.16. FN_MODEOUT register - ERRCTRL_FNMODEOUT
4.4.17. All Alarms After Fault Injection - ERRCTRL_FNGIALARMS
4.4.18. Error Controller Context Register - ERRCTRL_FNGICTXT4
4.4.19. CMP Mismatch CONTEXT Registers - ERRCTRL_FNGICMPCTXT0 … ERRCTRL_FNGICMPCTXT3
4.4.20. STATISTICS registers: ERRCTRL_FNGISTAT0 and ERRCTRL_FNGISTAT4
4.4.21. State register - ERRCTRL_FNPERIPHGI4
B. Appendix
Assumptions:
- A Lockstep-disabled Nios® V processor (Core 1) acts as the System Supervisor to manage a Lockstep-enabled Nios® V processor (Core 2).
- Lockstep Configuration Interface of Core 2 is connected to Data Manager of Core 1.
- The starting address of the Configuration Interface is 0xA0000.
Reading Generated Alarms
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
//Reading Alarms (ERRCTRL_FNGIALARMS)
unsigned int read_alarm = IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD498);
if(!read_alarm)
{
printf(“No Alarms”);
}
else
{
if(read_alarm&0x1) printf(“Alarm0\n”);
if(read_alarm&0x2) printf(“Alarm1\n”);
if(read_alarm&0x4) printf(“Alarm2\n”);
if(read_alarm&0x8) printf(“Alarm3\n”);
if(read_alarm&0x10) printf(“Alarm4\n”);
if(read_alarm&0x10000) printf(“Alarm16\n”);
if(read_alarm&0x20000) printf(“Alarm17\n”);
if(read_alarm&0x80000) printf(“Alarm19\n”);
}
}
Reading fRSmartComp State
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
//Reading fRSmartComp state (ERRCTRL_FNPERIPHGI4)
unsigned int read_state = IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD4E4);
switch(read_state)
{
case 0x1: printf(“DISABLED”); break;
case 0x2: printf(“OD”); break;
case 0x4: printf(“FCS”); break;
default: printf(“This is not expected.”);
}
}
Reading Mismatch Comparator Slices
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
//Reading Mismatch Comparator Slices (ERRCTRL_FNGICMPCTXT0)
unsigned int read_slice = IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD4B0);
if(!read_slice)
{
printf(“No mismatch”);
}
else
{
for(int i=0; i<23; i++)
{
if(read_slice&0x1) printf(“Mismatch in Slice %d\n”, i);
read_slice=read_slice/2;
}
}
}
Injecting Alarm Faults
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
/*
* Before Alarm Fault Injection
* 1. Read Alarms (Expecting no alarms)
* 2. Read fRSmartComp state (Expecting OD state)
*/
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
/*
* Start Alarm4 Fault Injection (ERRCTRL_ALARM_INJ)
*/
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD448, 0x10);
/*
* After Alarm Fault Injection
* 1. Read Alarms (Expecting a new Alarm4)
* 2. Read fRSmartComp state (Expecting OD state)
*/
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
/*
* Stop Alarm4 Fault Injection
* 1. Read Alarms (Expecting no alarms)
* 2. Read fRSmartComp state (Expecting OD state)
*/
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD448, 0x0);
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
}
Injecting Root Faults
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
/*
* Before Root Fault Injection
* 1. Read Alarms (Expecting no alarms)
* 2. Read fRSmartComp state (Expecting OD state)
* 3. Read mismatch slice (Expecting no mismatch)
*/
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
//Refer to Example 3 Reading Mismatch Comparator Slices
/*
* Configure and Start Root Fault Injection
* 1. Select BUS_D_CNTRL as target slice (ERRCTRL_PGO0)
* 2. Inject Comparator Self-detection
* with faulty frSmartComp (ERRCTRL_ROOT_INJ)
*/
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD460, 0x4);
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD444, 0x5);
/*
* After Root Fault Injection
* 1. Read Alarms (Expecting a new Alarm1, Alarm2, Alarm4)
* 2. Read fRSmartComp state (Expecting FCS state)
* 3. Read mismatch slice (Expecting no mismatch,
* and not affected by root fault injection)
*/
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
//Refer to Example 3 Reading Mismatch Comparator Slices
/*
* Stop Root Fault Injection
* No Effects due to Sticky Faults
* 1. Read Alarms (Expecting the same Alarm1, Alarm2, Alarm4)
* 2. Read fRSmartComp state (Expecting the same FCS state)
* 3. Read mismatch slice (Expecting the same no mismatch)
*/
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD444, 0x0);
//Refer to Example 1 Reading Generated Alarms
//Refer to Example 2 Reading fRSmartComp State
//Refer to Example 3 Reading Mismatch Comparator Slices
/*
* Reset Processor to Clear Root Faults
*/
}
Startup Procedure
#define LOCKSTEP_CONFIG_BASE_ADDR 0x000A0000
int main()
{
/*
* Enter main() after Nios V processor initialization is successful
*/
/*
* Configure fRSmartComp
* 1. Enable INTREQ generation (ERRCTRL_INTREQ_CONF)
* 2. Verify no alarm mask (ERRCTRL_MASK*)
* 3. Check default alarms’ severity (ERRCTRL_ROUT*)
* 4. Check frSmartComp Enable counter (ERRCTRL_PGO4)
*/
// 1. Enable INTREQ generation for ERROR-type alarm
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD420, 0x25);
// 2. Verify no alarm mask
unsigned int maskA =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD44C)&0xffffff;
unsigned int maskB =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD450)&0xffffff;
if((maskA == 0x555555)&&(maskB == 0x555555))
{
printf(“All alarms are unmasked.\n”);
}
// 3. Check default alarms’ severity
unsigned int severityA =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD454)&0xffffff;
unsigned int severityB =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD458)&0xffffff;
if((severityA == 0xe8fca8)&&(severityB == 0xaa0000))
{
printf(“All alarms are reset to default severity.\n”);
}
// 4. Check frSmartComp Enable counter
unsigned int en_count =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD470)&0xf;
printf(“System Supervisor can trigger %d fRSmartComp Enable command before
triggering Alarm17.\n”, en_count+1);
/*
* Provide timeout acknowledgment (ERRCTRL_TIMEOUT_ACK)
* Verify timeout counter stopped (ERRCTRL_TIMEOUT) by
* delaying more than timeout period
* Max timeout period at 100MHz processor clock is 10.44 milliseconds
*/
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD428, 0x78A5C3E1);
IOWR_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD428, 0x875A3C1E);
unsigned char count1 = IORD_8DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD425);
usleep(10000);
unsigned char count2 = IORD_8DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD425);
if(count1 == count2) printf(“Timeout acknowledged.\n”);
/*
* Disable timeout (ERRCTRL_TIMEOUT)
* 1. Unlock ERRCTRL_TIMEOUT
* 2. Verify unlocked status
* 3. Write new timeout deadline as 0 (Disable)
* 4. Lock ERRCTRL_TIMEOUT
*/
IOWR_8DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD427, (0x19<<1));
unsigned int timeout_csr =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD424);
printf("Timeout Period = %d\n", timeout_csr&0xff);
if(timeout_csr&0x01000000)
{
printf(“Unlocked Success.\n”);
} else
{
printf(“Still Locked. Failed to unlock.\n”);
}
IOWR_8DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD424, 0);
IOWR_8DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD427, 0);
timeout_csr =
IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD424);
if(timeout_csr&0x01000000)
{
printf(“Still Unlocked. Failed to lock.\n”);
} else
{
printf(“Locked Success.\n”);
}
timeout_csr = IORD_32DIRECT(LOCKSTEP_CONFIG_BASE_ADDR, 0xD424);
printf("Timeout Period = %d\n", timeout_csr&0xff);
if((timeout_csr&0xff) == 0) printf("Timeout disabled.\n");
/*
* Check no alarms
* If ALARM0 ~ ALARM4, a mismatch happens during startup.
* If ALARM16, timeout acknowledgement failed
* If ALARM19, either wrong key when disabling timeout or internal error
*/
//Refer to Example 1 Reading Generated Alarms
}