[Oberon] FPGA - Memory Map

Paul Reed paulreed at paddedcell.com
Mon Dec 11 12:15:21 CET 2017


Hi Tomas,

> In `vid.v' we have this memory origin set
> localparam Org = 18'b1101_1111_1111_0000_00;  // DFF00: adr of vcnt=1023
> But how does $DFF00 correspond to memory limit set by BootLoader.Mod?
> MemLim = 0E7EF0H;

The hardware line counter vcnt is counting up from 0 to 801 and then
repeating, as the pixel data is sent to the VGA connector from top to
bottom, the normal direction for video refresh (ie, normal for hardware
people).

802 lines corresponds to the entire vertical retrace period, including the
blank section (which is a legacy from cathode-ray tubes which took time to
re-position to the top left).

On the other hand, Prof. Wirth's framebuffer designs have the origin (0,
0) in the bottom left, from the software point of view, with y increasing
from bottom to top, like graphs (ie, normal for mathematicians).

So if we need to reverse the coordinate system in the y direction, the
easiest way is for the hardware to do it: in this case vcnt is inverted
(ones' complement) when the frame buffer address is formed in

   assign vidadr = Org + {3'b0, ~vcnt, hword};

This maps vcnt = 0 (000H, ie ~3FFH), ie the top line, y=767, to word
addresses

    1101_1111_1111_0000_00 + 000(1_1111_1111_1)xxx_xx =
1111_1111_1110_1xxx_xx

ie byte addresses 0FFE80H-0FFEFFH;

and vcnt = 767 (2FFH, ie ~100H), ie the bottom (visible) line, y=0, to
word addresses

    1101_1111_1111_0000_00 + 000(0_1000_0000_0)xxx_xx =
1111_0111_1111_0xxx_xx

ie byte addresses 0E7F00H-0E7F7FH.

This is indeed the framebuffer address base = 0E7F00H used by the Display
module.

It would have been nicer to put the framebuffer on a better memory
alignment boundary, like 0E0000H, or 0E8000H, because this would have
saved the need for an adder, but I was asked to respect the memory-mapped
I/O area which was already defined at 0FFFC0H-0FFFFFH.

I proposed putting the framebuffer at memory address zero, but Prof. Wirth
didn't like that much either.  As it is, we still waste a little bit of
memory (0FFF00H-0FFFBFH) but that's effectively "reserved for future use".
 So we ended up with the highest reasonable address where the horizontal
component hword would not be involved in the adder.

Of course, the final question is, why does the bootloader choose as its
limit something below 0E7F00H, ie 0E7EF0H, as you point out?

I think a clue here is given in the simplified serial-only version of the
bootloader, where StackOrg is set to 0E7EF0H, rather than 80000H in the
disk (SD-Card) case.

This came up during development from the need to provide space for the
stack frame which will be assumed when returning from an abort (ie reset
button pressed).  (Even now, procedure Abort in module System declares a
local variable n, and implicitly has a storage location for the return
address, the LNK register on entry.  With the disk version, it seems that
pressing the abort button might corrupt the first two words of the heap,
at 80000H.  It has been noted that the memory management also writes to
other such "unauthorised" locations, but without consequence in practice.)

HTH,
Paul




More information about the Oberon mailing list