How do you initialize Xilinx ISOCM memory using DCR interface

I'm trying to use the Xilinx ISOCM memory in a Virtex-II Pro. I can't seem to get it to actually write to the ISOCM BRAMs.

In .mhs file I have:

BEGIN ppc405 PARAMETER INSTANCE = ppc405_0 PARAMETER HW_VER = 2.00.c PARAMETER C_ISOCM_DCR_BASEADDR = 0b0100000000 PARAMETER C_DSOCM_DCR_BASEADDR = 0b1000000000 PARAMETER C_DCR_RESYNC = 2 BUS_INTERFACE ISOCM = iocm BUS_INTERFACE DSOCM = docm PORT BRAMISOCMCLK = sys_clk_s PORT BRAMDSOCMCLK = sys_clk_s PORT DCRCLK = sys_clk_s . . . END

BEGIN isocm_v10 PARAMETER INSTANCE = iocm PARAMETER HW_VER = 2.00.a PARAMETER C_ISCNTLVALUE = 0x83 // Note ppc_clk_s is 2 times sys_clk_s PORT ISOCM_Clk = sys_clk_s PORT sys_rst = sys_bus_reset END

BEGIN isbram_if_cntlr PARAMETER INSTANCE = iocm_cntlr PARAMETER HW_VER = 3.00.a PARAMETER C_BASEADDR = 0x01000000 PARAMETER C_HIGHADDR = 0x01003FFF BUS_INTERFACE ISOCM = iocm BUS_INTERFACE DCR_WRITE_PORT = isocm_porta BUS_INTERFACE INSTRN_READ_PORT = isocm_portb END

BEGIN bram_block PARAMETER INSTANCE = isocm_bram PARAMETER HW_VER = 1.00.a BUS_INTERFACE PORTA = isocm_porta BUS_INTERFACE PORTB = isocm_portb END

In .mss I have:

BEGIN DRIVER PARAMETER DRIVER_NAME = generic PARAMETER DRIVER_VER = 1.00.a PARAMETER HW_INSTANCE = iocm_cntlr END

Then in my C code, I do the following:

// Initialize ISINIT register to starting address. // This works when I read it back. mtdcr(0x100, 0x01000000);

I'm using 0x100 for the DCRN address above since I set the base address of the IOCM DCR to 0x100 in the MHS, and the offset of the ISINIT from that base is 0.

// Write a value to ISFILL register. mtdcr(0x101, 0xFFFFFFFF);

The write to the ISFILL works and increments ISINIT as it should. Reading back the value in ISFILL gives 0xFFFFFFFF as it should, but this is just the register, not what is in BRAM itself. However, when I go to read the IOCM memory itself using:

long *p = (long *) 0x01000000; long x = *p;

I still get 0.

So it seems the like everything is working except the value in ISFILL is not being transferred to the actual BRAM. What am I missing? Do I need to create a DCR bus to the IOCM? Do I need to somehow enable DCR writes?

Any help would be appreciated.

Reply to
David Hand
Loading thread data ...

Hi David,

you can't read the ISOCM in Virtex-II Pro. You can only write it and execute from it.

- Peter

David Hand wrote:

Reply to
Peter Ryser

Peter,

That worked! I copied some code to the ISOCM and called the function and it works fine, so it was copying to the BRAM all along. I did not realize the ISOCM was protected from memory reads.

Thanks a million; it would have taken me forever to figure that one out.

I wonder if I could bother you to could clarify a couple of other points:

In AR# 19804 at

formatting link
the solution does not seem to jive with my understanding of the problem. The problem description seems to be saying that placing getchar() in ISOCM would be a problem, but the solution seems to be saying calling getchar() from a function that is itself in ISOCM should be avoided. But if getchar() itself is left in regular memory, why should calling it be an issue?

AR# 19099, at

formatting link
seems to imply using OCM in any code where an exception could occur could be very dangerous. It looks like the only workaround is to write everything in assembler. Is that an accurate statement?

Thanks, Dave

Peter Ryser wrote:

Reply to
David Hand

Dave,

you need to look at OCM like caches in a Harvard architecture, i.e. dedicated blocks for data and instruction accesses. Like it is not possible during program execution to read data from the instruction cache it is not possible to read data from the instruction cache. IOCM is actually a little bit worse because the data (code) gets in there through the debugger or a program like you have written and not through a processor initiated load operation, i.e. data loaded by the processor through a load operation can never end up in the instruction cache.

For OCM that means that the compiler and linker strictly need to separate instruction and data sections. Now, the newlib libraries are written something like this: .text data: .long 0xdeadbeef code: lis r2, data@h ori r2, r2, data@l lwz r3, 0(r2)

Instruction and data are mixed within a .text segment. When the debugger or your program loads that code into ISOCM the "data" variable becomes inaccessible to the "code" because of the Harvard nature of OCM.

This problem only occurs on the DOCM and not on the IOCM. The best way to work around this problem is to turn off interrupts and exceptions before accessing data in the DOCM. If that does not work, then, yes you have to write the routines that access the DOCM in assembler or disassemble the compiler generated code and inspect it so that the instruction sequence doesn't occur.

- Peter

Reply to
Peter Ryser

That part makes sense. It's clear I can't load newlib code into ISOCM. The part I don't understand is why I can't make a call from code that is in ISOCM to a newlib function that is left in say SRAM. In other words, am I allowed to do this:

void MyISOCMFunction() // Function in ISOCM { c = getchar(); // getchar() in usual place (say SRAM).

}

Thanks

Reply to
David Hand

David,

that should work. You might need to map the ISOCM within 24 address bits (max. address offset in branch instruction) of the SRAM or advise the compiler to generate long-jumps.

- Peter

David Hand wrote:

Reply to
Peter Ryser

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.