Microblaze V4 / FSL2.0 - putfsl_interruptable() not working reliably

Hello,

I have build a system consisting of two Microblazes connected with an FSL channel. When using the putfsl_interruptable() macro data gets lost. If the FSL FIFO is full sometimes putfsl_interruptable() returns without having written the data to the FSL.

I've used the debugger to step through the code at assembler level and nput sometimes fails to set the Carry bit in MSR when the FSL is actually full. So, to me, this looks like a MicroBlaze and/or FSL bug.

I have found a post in this newsgroup from Bernhard Sputh who reports quite similiar problems. He could work around this issue by disabling interrupts. Sadly, disabling interrupts while calling the

*_interruptable() doesn't help in my case.

I'm using the Microblaze Version that comes with EDK 8.1.02. Are there any errata sheets for the FSL and/or Microblaze available? I found no such thing on the Xilinx web site.

Best regards, Andreas

Reply to
Andreas Hofmann
Loading thread data ...

Hi,

If you using putfsl_interruptable() then you are using this macro:

#define getfsl_interruptible(val, id) asm volatile ("\n1:\n\tnget\t%0,rfsl" stringify(id) "\n\t" \ "addic\tr18,r0,0\n\t" \ "bnei\tr18,1b\n" \ : "=d" (val) :: "r18")

What this actually does is to use the non-blocking get instruction which will try to put a value to the FSL but will not stall if it can't. If it fails due to that the FSL is full it will set the carry flag C in the MSR register. The instruction addic r18,r0,0 will add this Carry value to the r18 register and it will continue to loop until the r18 is zero (Carry = 0). If you get an interrupt, the interrupt handler must assure that the carry bit in MSR is restore on the return, otherwise a failed nput will be consider as a success.

What kind of interrupt_handler are you using?

Göran Bilski

Reply to
Göran Bilski

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

Reply to
Andreas Hofmann

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.