Hi,
the first time I discovered this behaviour was in a xilkernel environment. I have not yet looked in the xilkernel source code, if the carry bit is saved and restored.
I wrote a small test program which does not use interrupts or the xilkernel. When I use putfsl_interruptible() it fails realiably. The MicroBlazes and the supporting system is stripped to bare necessity. The program and the system.mhs is attached at the end of this post. The number of cycles between two reads of the FSL by MicroBlaze 0 influences the number of errors seen.
BTW: It would be nice if the Xilinx documentation states that the fsl_isinvalid() macro depends on the Carry bit set by the nget()/nput() macros. When programming on C and not on Assembler level this is, to me, not obvious.
Andreas.
//-------------- test program ------------------------------------ #include "xparameters.h" #include "mb_interface.h" #include "stdio.h"
int main() { int max_iteration = 0x10000000; int error_count = 0; int i = 0; int j = 0; int delay;
microblaze_disable_interrupts();
#ifdef MB0 //-------------- MicroBlaze 0------------------------------------ print("Starting ...\r\n"); while( i < max_iteration ) { getfsl(j, 0);
for( delay = 3; delay > 0; delay-- ) asm volatile ("nop\n\t");
if( i != j ) { print("Error at i=0x");putnum(i);print(" j: 0x");putnum(j); print("\r\n"); i = j; error_count++; } i++; } if( error_count == 0 ) print("...finished sucessfully.\r\n"); else { print("error_count=0x");putnum(error_count);print("\r\n"); } #else //-------------- MicroBlaze 1------------------------------------- while ( i < max_iteration ) { putfsl_interruptible(i, 0); i++; } #endif
return 0; } //-------------- system.mhs ------------------------------------- ############################################################################## # Created by Base System Builder Wizard for Xilinx EDK 8.1.02 Build EDK_I.20.4 # Tue Sep 05 11:14:00 2006 # Target Board: Custom # Family: virtex4 # Device: xc4vfx20 # Package: ff672 # Speed Grade: -10 # Processor: Microblaze # System clock frequency: 100.000000 MHz # Debug interface: On-Chip HW Debug Module # On Chip Memory : 64 KB # ##############################################################################
PARAMETER VERSION = 2.1.0
PORT fpga_0_RS232_RX_pin = fpga_0_RS232_RX, DIR = I PORT fpga_0_RS232_TX_pin = fpga_0_RS232_TX, DIR = O PORT sys_clk_pin = dcm_clk_s, DIR = I, SIGIS = DCMCLK PORT sys_rst_pin = sys_rst_s, DIR = I
BEGIN opb_opb_lite PARAMETER INSTANCE = opb_opb_lite_0 PARAMETER HW_VER = 1.00.a PARAMETER C_DEC0_BASEADDR = 0x40600000 PARAMETER C_DEC0_HIGHADDR = 0x4060FFFF BUS_INTERFACE SOPB = mb1_opb BUS_INTERFACE MOPB = mb0_opb END
BEGIN microblaze PARAMETER INSTANCE = microblaze_1 PARAMETER HW_VER = 4.00.a PARAMETER C_USE_FPU = 0 PARAMETER C_DEBUG_ENABLED = 1 PARAMETER C_FSL_LINKS = 1 PARAMETER C_NUMBER_OF_PC_BRK = 2 PARAMETER C_USE_BARREL = 0 PARAMETER C_USE_DIV = 0 PARAMETER C_USE_MSR_INSTR = 0 PARAMETER C_USE_PCMP_INSTR = 0 BUS_INTERFACE ILMB = mb1_ilmb BUS_INTERFACE DLMB = mb1_dlmb BUS_INTERFACE SFSL0 = mb0_master_fsl BUS_INTERFACE DOPB = mb1_opb BUS_INTERFACE IOPB = mb1_opb BUS_INTERFACE MFSL0 = mb1_master_fsl PORT CLK = sys_clk_s PORT DBG_CLK = microblaze_1_DBG_CLK PORT DBG_TDI = microblaze_1_DBG_TDI PORT DBG_TDO = microblaze_1_DBG_TDO PORT DBG_REG_EN = microblaze_1_DBG_REG_EN PORT DBG_CAPTURE = microblaze_1_DBG_CAPTURE PORT DBG_UPDATE = microblaze_1_DBG_UPDATE END
BEGIN microblaze PARAMETER INSTANCE = microblaze_0 PARAMETER HW_VER = 4.00.a PARAMETER C_USE_FPU = 0 PARAMETER C_USE_HW_MUL = 1 PARAMETER C_DEBUG_ENABLED = 1 PARAMETER C_FSL_LINKS = 1 PARAMETER C_USE_BARREL = 0 PARAMETER C_USE_DIV = 0 PARAMETER C_USE_MSR_INSTR = 0 PARAMETER C_USE_PCMP_INSTR = 0 PARAMETER C_NUMBER_OF_PC_BRK = 2 BUS_INTERFACE DLMB = mb0_dlmb BUS_INTERFACE ILMB = mb0_ilmb BUS_INTERFACE DOPB = mb0_opb BUS_INTERFACE IOPB = mb0_opb BUS_INTERFACE SFSL0 = mb1_master_fsl BUS_INTERFACE MFSL0 = mb0_master_fsl PORT CLK = sys_clk_s PORT DBG_CLK = microblaze_0_DBG_CLK PORT DBG_TDI = microblaze_0_DBG_TDI PORT DBG_TDO = microblaze_0_DBG_TDO PORT DBG_REG_EN = microblaze_0_DBG_REG_EN PORT DBG_CAPTURE = microblaze_0_DBG_CAPTURE PORT DBG_UPDATE = microblaze_0_DBG_UPDATE END
BEGIN opb_v20 PARAMETER INSTANCE = mb1_opb PARAMETER HW_VER = 1.10.c PARAMETER C_EXT_RESET_HIGH = 0 PORT SYS_Rst = sys_rst_s PORT OPB_Clk = sys_clk_s END
BEGIN fsl_v20 PARAMETER INSTANCE = mb1_master_fsl PARAMETER HW_VER = 2.00.a PARAMETER C_EXT_RESET_HIGH = 0 PARAMETER C_FSL_DEPTH = 16 PARAMETER C_USE_CONTROL = 0 PORT FSL_Clk = sys_clk_s PORT SYS_Rst = sys_rst_s END
BEGIN bram_block PARAMETER INSTANCE = mb1_lmb_bram PARAMETER HW_VER = 1.00.a BUS_INTERFACE PORTA = mb1_ilmb_port BUS_INTERFACE PORTB = mb1_dlmb_port END
BEGIN lmb_bram_if_cntlr PARAMETER INSTANCE = mb1_ilmb_cntrl PARAMETER HW_VER = 1.00.b PARAMETER C_BASEADDR = 0x00000000 PARAMETER C_HIGHADDR = 0x0000FFFF BUS_INTERFACE SLMB = mb1_ilmb BUS_INTERFACE BRAM_PORT = mb1_ilmb_port END
BEGIN lmb_v10 PARAMETER INSTANCE = mb1_ilmb PARAMETER HW_VER = 1.00.a PARAMETER C_EXT_RESET_HIGH = 0 PORT LMB_Clk = sys_clk_s PORT SYS_Rst = sys_rst_s END
BEGIN lmb_bram_if_cntlr PARAMETER INSTANCE = mb1_dlmb_cntrl PARAMETER HW_VER = 1.00.b PARAMETER C_BASEADDR = 0x00000000 PARAMETER C_HIGHADDR = 0x0000FFFF BUS_INTERFACE SLMB = mb1_dlmb BUS_INTERFACE BRAM_PORT = mb1_dlmb_port END
BEGIN lmb_v10 PARAMETER INSTANCE = mb1_dlmb PARAMETER HW_VER = 1.00.a PARAMETER C_EXT_RESET_HIGH = 0 PORT LMB_Clk = sys_clk_s PORT SYS_Rst = sys_rst_s END
BEGIN opb_v20 PARAMETER INSTANCE = mb0_opb PARAMETER HW_VER = 1.10.c PARAMETER C_EXT_RESET_HIGH = 0 PORT SYS_Rst = sys_rst_s PORT OPB_Clk = sys_clk_s END
BEGIN fsl_v20 PARAMETER INSTANCE = mb0_master_fsl PARAMETER HW_VER = 2.00.a PARAMETER C_EXT_RESET_HIGH = 0 PARAMETER C_FSL_DEPTH = 16 PARAMETER C_USE_CONTROL = 0 PORT FSL_Clk = sys_clk_s PORT SYS_Rst = sys_rst_s END
BEGIN bram_block PARAMETER INSTANCE = mb0_lmb_bram PARAMETER HW_VER = 1.00.a BUS_INTERFACE PORTA = mb0_ilmb_port BUS_INTERFACE PORTB = mb0_dlmb_port END
BEGIN lmb_bram_if_cntlr PARAMETER INSTANCE = mb0_ilmb_cntlr PARAMETER HW_VER = 1.00.b PARAMETER C_BASEADDR = 0x00000000 PARAMETER C_HIGHADDR = 0x0000ffff BUS_INTERFACE SLMB = mb0_ilmb BUS_INTERFACE BRAM_PORT = mb0_ilmb_port END
BEGIN lmb_v10 PARAMETER INSTANCE = mb0_ilmb PARAMETER HW_VER = 1.00.a PARAMETER C_EXT_RESET_HIGH = 0 PORT SYS_Rst = sys_rst_s PORT LMB_Clk = sys_clk_s END
BEGIN lmb_bram_if_cntlr PARAMETER INSTANCE = mb0_dlmb_cntlr PARAMETER HW_VER = 1.00.b PARAMETER C_BASEADDR = 0x00000000 PARAMETER C_HIGHADDR = 0x0000ffff BUS_INTERFACE SLMB = mb0_dlmb BUS_INTERFACE BRAM_PORT = mb0_dlmb_port END
BEGIN lmb_v10 PARAMETER INSTANCE = mb0_dlmb PARAMETER HW_VER = 1.00.a PARAMETER C_EXT_RESET_HIGH = 0 PORT SYS_Rst = sys_rst_s PORT LMB_Clk = sys_clk_s END
BEGIN opb_uartlite PARAMETER INSTANCE = mb0_RS232 PARAMETER HW_VER = 1.00.b PARAMETER C_BAUDRATE = 9600 PARAMETER C_DATA_BITS = 8 PARAMETER C_ODD_PARITY = 0 PARAMETER C_USE_PARITY = 0 PARAMETER C_CLK_FREQ = 100000000 PARAMETER C_BASEADDR = 0x40600000 PARAMETER C_HIGHADDR = 0x4060ffff BUS_INTERFACE SOPB = mb0_opb PORT OPB_Clk = sys_clk_s PORT RX = fpga_0_RS232_RX PORT TX = fpga_0_RS232_TX END
BEGIN opb_mdm PARAMETER INSTANCE = debug_module PARAMETER HW_VER = 2.00.a PARAMETER C_MB_DBG_PORTS = 2 PARAMETER C_USE_UART = 0 PARAMETER C_UART_WIDTH = 8 PORT OPB_Clk = sys_clk_s PORT Dbg_Clk_0 = microblaze_0_DBG_CLK PORT Dbg_TDI_0 = microblaze_0_DBG_TDI PORT Dbg_TDO_0 = microblaze_0_DBG_TDO PORT Dbg_Reg_En_0 = microblaze_0_DBG_REG_EN PORT Dbg_Capture_0 = microblaze_0_DBG_CAPTURE PORT Dbg_Update_0 = microblaze_0_DBG_UPDATE PORT Dbg_Clk_1 = microblaze_1_DBG_CLK PORT Dbg_TDI_1 = microblaze_1_DBG_TDI PORT Dbg_TDO_1 = microblaze_1_DBG_TDO PORT Dbg_Reg_En_1 = microblaze_1_DBG_REG_EN PORT Dbg_Capture_1 = microblaze_1_DBG_CAPTURE PORT Dbg_Update_1 = microblaze_1_DBG_UPDATE END
BEGIN dcm_module PARAMETER INSTANCE = dcm_0 PARAMETER HW_VER = 1.00.a PARAMETER C_CLK0_BUF = TRUE PARAMETER C_CLKIN_PERIOD = 10.000000 PARAMETER C_CLK_FEEDBACK = 1X PARAMETER C_DLL_FREQUENCY_MODE = LOW PARAMETER C_EXT_RESET_HIGH = 1 PORT CLKIN = dcm_clk_s PORT CLK0 = sys_clk_s PORT CLKFB = sys_clk_s PORT RST = net_gnd PORT LOCKED = dcm_0_lock END