1. SoC Course WS 2002/2003 Week #7
Expanding the MicroBlaze System
Introduction
This week, we will expand our MicroBlaze design to a full-blown system providing
the following features:
⢠VGA output
⢠LCD output
⢠16-bit memory controller
⢠code and data stored in external memory
Instead of performing the required steps to upgrade your design from week 4
yourself, we will present a guided tour through the complete design here.
Take your time to look through the code, and try simple variations on the
given project. You will be implementing your own peripherals during the
next extercises!
page 1
2. SoC Course WS 2002/2003 Week #7
VGA output
The VGA output may be used to display textural information on a standard PC
monitor. The VGA peripheral comes complete with drivers, so that the peripheral
may be used to redirect STDOUT.
The peripheralâs hardware design files are located in the
opb_peripherals/te_vga_v1_00_a directory. The peripheralâs driver source files
are located in the drivers/drv_te_vga_v1_00_a directory. You are invited to
browse through these files for further insights.
The peripheral is instantiated in the MHS file as follows:
SELECT slave te_vga
CSET attribute INSTANCE = vgacon
CSET attribute HW_VER = 1.00.a
CSET attribute C_BASEADDR = 0xF4800000
CSET attribute C_HIGHADDR = 0xF4FFFFFF
CSET signal clk25 = clk25
CSET signal r = r
CSET signal g = g
CSET signal b = b
CSET signal rb = rb
CSET signal gb = gb
CSET signal bb = bb
CSET signal hsync = hsync
CSET signal vsync = vsync
END
The peripheral is mapped into the main memory at address F4800000. The video
screen is organized in 32 lines with 64 characters each. This results in 2kB of video
memory. As the address is not fully decoded, the video memory is mirrored
throughout the complete area from C_BASEADDR to C_HIGHADDR.
The signals r,g,b and rb, gb, bb carry the color information for up to 64 colors. The
analog signals required by the VGA monitor are created using a passive resistor
network. The horizontal and vertical sync pulses are created from the hsync and
vsync signals. In addition to these outputs, the VGA peripherals requires the
separate clock input clk25 which provides a 25MHz pixel clock. As standard VGA
monitors require relatively high accuracy on their timings, a suitable clock cannot be
derived from the 48MHz input used for the MicroBlaze cpu.
The drivers for the VGA peripheral are specified in the MSS file as follows:
SELECT INSTANCE vgacon
CSET attribute DRIVER = drv_te_vga
CSET attribute DRIVER_VER = 1.00.a
END
To redirect stdout to the VGA, replace the STDOUT definition as follows:
# SET attribute STDOUT = uart
SET attribute STDOUT = vgacon
Questions
⢠what is the screen resolution in pixels?
⢠what is the size of the character generator ROM in bytes?
⢠draw a simple block diagram of the VGA peripheral showing the bus
interface, the timing generator, the video memory, and the character generator
⢠what happens, if output reaches line 33, how is scrolling implemented? Are
there any other solutions?
⢠which peripheral would you prefer to print debug messages, UART or
VGA? why?
page 2
3. SoC Course WS 2002/2003 Week #7
LCD output
The LCD output may be used to display textural information on-board. While
usage of the LCD panel eases handling, the LCD has some significant drawbacks:
⢠timing is slow
⢠display is small
⢠LCD has own display buffer
⢠requires 12 pins
Typical cycle time of LCD controllers is 500ns, which is a long time for a CPU
running at 48MHz. The display is only 2 lines with 16 characters each, which is not
enough for sophisticated output. The display provides its own display buffer,
which makes implementation of scrolling difficult or very slow. Still, as no additional
monitor is required, the LCD is a useful peripheral for simple text output.
The peripheralâs hardware design files are located in the
opb_peripherals/te_lcd_v1_00_a directory. The peripheralâs driver source files are
located in the drivers/drv_te_lcd_v1_00_a directory.
The peripheral is instantiated in the MHS file as follows:
SELECT SLAVE te_lcd
CSET attribute INSTANCE = lcdcon
CSET attribute HW_VER = 1.00.a
CSET attribute C_BASEADDR = 0xF3800000
CSET attribute C_HIGHADDR = 0xF38000FF
CSET signal lcd_rs = lcd_rs
CSET signal lcd_rwn = lcd_rwn
CSET signal lcd_e = lcd_e
CSET signal lcd_dr = lcd_dr
CSET signal lcd_db = lcd_db
END
The driver is specified in the MSS file as follows:
SELECT INSTANCE lcdcon
CSET attribute DRIVER = drv_te_lcd
CSET attribute DRIVER_VER = 1.00.a
END
Before printing to the LCD, the controller needs to be initialized. To do so, put the
following line into your code:
lcd_init();
This will initialize your display with an empty screen, cursor off, and an 8-bit interface
to the MicroBlaze system.
Questions
⢠is it possible to attach the LCD controller to an 8-bit memory bus?
⢠how would you implement scrolling? are there alternatives?
page 3
4. SoC Course WS 2002/2003 Week #7
memory controller
The memory controller attaches external 16-bit memory to the 32-bit MicroBlaze
system using dynamic bus resizing. This latter is the key feature required, to
execute program code from external 16-bit memory. To maximize CPU
performance, the memory controller implements different timings for RAM read,
RAM write, and access to the Flash memory.
The peripheralâs hardware design files are located in the
opb_peripherals/te_mem_v1_00_a directory. The peripheralâs driver source files
are located in the drivers/drv_te_mem_v1_00_a directory.
The peripheral is instantiated in the MHS file as follows:
SELECT SLAVE te_mem
CSET attribute INSTANCE = memcon
CSET attribute HW_VER = 1.00.a
CSET attribute C_BASEADDR = 0x00800000
CSET attribute C_HIGHADDR = 0x00FFFFFF
CSET signal mem_a = mem_a
CSET signal mem_d = mem_d
CSET signal mem_wen = mem_wen
CSET signal flash_cen = flash_cen
CSET signal flash_oen = flash_oen
CSET signal flash_rdy = flash_rdy
CSET signal flash_8n = flash_8n
CSET signal ram_csn = ram_csn
CSET signal ram_oen = ram_oen
CSET signal ram_blen = ram_blen
CSET signal ram_bhen = ram_bhen
CSET signal cpld_csn = cpld_csn
CSET signal cpld_rwn = cpld_rwn
END
Beginning with address 0x00800000, the memory map is as follows:
0080_0000 - 0087_ffff SRAM
00c0_0000 - 00c3_ffff Flash (factory configuration)
00c4_0000 - 00c7_ffff Flash (user configuration)
00c8_0000 - 00cf_ffff Flash (application space)
00e0_0000 push buttons
00e0_0002 dip switch
00e0_0004 LEDs
The driver is specified in the MSS file as follows:
SELECT INSTANCE memcon
CSET attribute DRIVER = drv_te_mem
CSET attribute DRIVER_VER = 1.00.a
END
The driver provides code to access the flash.
Please do not program the flash, unless instructed to do so. This will
save your tutor some time!!! Thank you.
Questions
⢠draw a simple diagram illustrating how the memory bus timing is generated
⢠what are the access times for RAM read, RAM write, and Flash? could this
be tweaked to run faster?
page 4
5. SoC Course WS 2002/2003 Week #7
running code from external memory
The maximum amount of memory implemented inside an XC2S300E part is 8kB.
This is not enough for sophisticated programs, especially as part of the memory is
already utilized by the peripherals. The solution is, to store code and data in
external memory.
Typically, program code is store in non-volatile memory, i.e. the on-board flash.
Storing your code in the flash memory leads to several problems:
⢠flash is read-only. this is a problem for initialized data
⢠segmenting code and data according to access attributes is complicated
⢠flash is slow. this reduces the overall performance of the system
To overcome these problems, the code and data are stored in flash, but are
copied into the RAM during system start-up. This functionality is implemented
using some stub code:
main()
{ long i, j;
const unsigned short* src;
unsigned short* dst;
void (*UserEntry)(void)= (void (*)(void))SRAM_BASEADDR;
src = (unsigned short*)FLASH_BASEADDR_APPL;
dst = (unsigned short*)SRAM_BASEADDR;
for (i= 0; i< FLASH_SIZE; i++)
{ *dst++ = *src++;
}
UserEntry();
}
The stub is compiled into the object module flashstub.out using the same options
as you used in your previous projects. The stub is stored in the LMB memory with
the following line in your MHS file:
SET attribute EXECUTABLE = code/flashstub.out
Please note, that the LMB contents for debugging and bootstrap modes remains
unchanged:
SET attribute XMDSTUB = code/xmdstub.out
SET attribute BOOTSTRAP = code/bootstub.out
The user firmware is compiled using the bootstrap option and its base address at
the beginning of the SRAM. We may now define plenty of stack space. See the
following gcc instruction in the Makefile:
code/system.out : lib/libc.a lib/libm.a $(PROGRAM_SOURCES)
mb-gcc
-g
-mxl-gp-opt
-xl-mode-bootstrap
-I./include
-L./lib
-Wl,-defsym -Wl,_STACK_SIZE=0x4000
-Wl,-defsym -Wl,_TEXT_START_ADDR=0x00800000
$(PROGRAM_SOURCES)
-o code/system.out
Questions
⢠illustrate the contents of LMB and external RAM for XMDSTUB and
EXECUTABLE modes
page 5