New Horizons






<< September 2007 >>
Sun Mon Tue Wed Thu Fri Sat
 01
02 03 04 05 06 07 08
09 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30


Table of content

New Horizons
What's new
Starting a blog
Writing a blog
I got a job

SystemC
SystemC from scratch. Part 1
SystemC from scratch. Part 2
SystemC from scratch. Part 3

ASIC/FPGA Design
Table of content
Index
FPGA design from scratch. Part 1
FPGA design from scratch. Part 2
FPGA design from scratch. Part 3
FPGA design from scratch. Part 4
FPGA design from scratch. Part 5
FPGA design from scratch. Part 6
FPGA design from scratch. Part 7
FPGA design from scratch. Part 8
FPGA design from scratch. Part 9
FPGA design from scratch. Part 10
FPGA design from scratch. Part 11
FPGA design from scratch. Part 12
FPGA design from scratch. Part 13
FPGA design from scratch. Part 14
FPGA design from scratch. Part 15
FPGA design from scratch. Part 16
FPGA design from scratch. Part 17
FPGA design from scratch. Part 18
FPGA design from scratch. Part 19
FPGA design from scratch. Part 20
FPGA design from scratch. Part 21
FPGA design from scratch. Part 22
FPGA design from scratch. Part 23
FPGA design from scratch. Part 24
FPGA design from scratch. Part 25
FPGA design from scratch. Part 26
FPGA design from scratch. Part 27
FPGA design from scratch. Part 28
FPGA design from scratch. Part 29
FPGA design from scratch. Part 30
FPGA design from scratch. Part 31
FPGA design from scratch. Part 32
FPGA design from scratch. Part 33
FPGA design from scratch. Part 34
FPGA design from scratch. Part 35
FPGA design from scratch. Part 36
FPGA design from scratch. Part 37
FPGA design from scratch. Part 38
FPGA design from scratch. Part 39
FPGA design from scratch. Part 40
FPGA design from scratch. Part 41
FPGA design from scratch. Part 42
FPGA design from scratch. Part 43
FPGA design from scratch. Part 44
FPGA design from scratch. Part 45
FPGA design from scratch. Part 46
FPGA design from scratch. Part 47
FPGA design from scratch. Part 48
FPGA design from scratch. Part 49
FPGA design from scratch. Part 50
Links
Acronyms and abbreviations
XCell Journals
CAD
A hardware designer's best friend
Zoo Design Platform
Linux
Installing Ubuntu Linux on a MacBook
Customizing Ubuntu Linux 1
Customizing Ubuntu Linux 2
Upgrading to Ubuntu 7.04
Install Ubuntu 7.04 with VMware
Making the virtual machine run faster
Ubuntu Links
A processor benchmark
Mac
Porting a Unix program to Mac OS X
Fixing a HyperTerminal in Mac OS X
A dream come true
Wireless freedom
Running
The New York City Marathon
Skiing/Skating
Kittelfjäll Lappland
Tour skating in Sweden and around the world
Top
Introduction
SSSK
Wild skating
Tour day
Safety equipment
A look at the equipment you need
Skate maintenance
Calendar
Links
Books, photos, films and videos
Weather forecasts
Travel
38000 feet above see level
A trip to Spain
Florida the sunshine state


Example Files
Verilog Testbench Body
Verilog Testcase
Verilog Setup
Simulation Result File
Simulation Report File




Photo Albums
Seaside Florida
Ronda Spain
Sevilla Spain
Cordoba Spain
Alhambra Spain
Kittelfjäll Lapland
Landsort Art Walk
Skating on thin ice


Favorites
Adventures in ASIC
ChipHit
Computer History Museum
Community of Sweden
DeepChip
Design & Reuse
Dilbert
EDA Cafe
EDA DesignLine
Embedded.com
EmbeddedRelated.com
FPGA Arcade
FPGA Blog
FPGA Central
FPGA Journal
FPGA World
MacApper
Mac geekery
Mac 2 Ubuntu
Get Perpendicular
Programmable Logic DesignLine
History of Linux
OpenCores
ORSoC
Simplehelp
SOCcentral
World of ASIC



New York City Marathon




If you want to be updated on this weblog Enter your email here:



rss feed



 
Sep 28, 2007
FPGA design from scratch. Part 44
Adding an External Memory Controller

We need a permanent storage for our Linux installation. The ML403 board contains a
flash memory which is the perfect place to store our Linux OS to to be used during bootup of our system. To be able to read to and write from the flash memory we have to add an External Memory Controller (EMC). Let's do that.



The EMC supports up to four memory banks. We will use only one.



Generate addresses

The flash memory that comes with the ML403 board is 512 MB and with a 32 bit databus we will have a 128 MB address range.

Software platform settings

We have to tell the software where the flash is located. Open the Software->Software Platform Settings window and select OS and Libraries. Here we specify which memory bank we use (0) and the name of the external memory controller.





OPB External Memory Controller

The OPB EMC receives control signals from the OPB to read and write to external memory devices. The OPB EMC provides an interface between the OPB and one to four external banks of memory components. The EMC supports OPB data bus widths of 8,16 & 32 bits, and memory subsystem widths of 8,16 & 32 bits. The OPB EMC supports the OPB V2.0 byte enable architecture. Any access size up to the width of the OPB data bus is permitted. When the width of the memory is less than the width of the OPB, multiple memory cycles are performed to transfer the data width of the bus if data-width matching has been enabled for that memory bank.
The OPB EMC provides basic read/write control signals and the ability to configure the access times for read, write, and recovery times when switching from read to write or write to read. When the OPB EMC is set for flash memory control it is organized like an SRAM interface. The OPB EMC assumes that the Flash programming circuitry is built into the Flash components and that the command interface to the Flash is handled in software.



                                                                                                                                                                                        
(Courtesy of Xilinx)


Top  Previous Next



Posted at 07:43 am by svenand
Make a comment  

 
Sep 5, 2007
FPGA design from scratch. Part 43
Installing a Linux OS

It has been a long and bumpy ride but now we start to see the
light in the tunnel. So keep up, stay onboard, we will soon reach the final destination. We are ready for the real challenge, installing a Linux OS in our embedded system.

Why using a Linux OS

Linux use in future embedded, mobile, and real-time projects will grow 278 percent over that in past projects, suggests a recent survey by Venture Development Corp. (VDC). Meanwhile, proprietary commercial embedded operating systems are holding steady, gaining customers from do-it-yourself OS users, but losing them just as fast to Linux, the analyst firm reports.

Embedded Linux OS

The MicroBlaze procssor has one drawback, it doesn't include a
Memory Management Unit (MMU). To overcome this limitation, development started early to come up with a Linux kernel that could be used on a MMU-less processor. This work lead to to the introduction of uClinux. Most of the work done in the uClinux was been incorporated into the Linux kernel development and the 2.6 Linux kernel is the first stable release with mainline support for processors, such as MicroBlaze, that do not have an MMU eliminating the need to apply and forward-port uClinux patches.

uClinux

The original uClinux was a derivative of Linux 2.0 kernel intended for microcontrollers without MMUs. However, the Linux/Microcontroller Project has grown both in brand recognition and coverage of processor architectures. Today's uClinux as an operating system includes Linux kernel releases for 2.0 2.4 and 2.6 as well as a collection of user applications, libraries and tool chains.

Finding a Linux OS

This table shows some of the Linux OSes that runs on a MicroBlaze processor.

 Distribution  Vendor  Information
 uClinux  OpenSource  
 PetaLinux  PetaLogix
 BlueCat Linux ME  LinuxWorks  Available ?
     

Third Party Real Time Operating Systems (RTOS) Support

This
table and this
table shows RTOS supporting PowerPC and MicroBlaze.


Application notes

You can find a number of
application notes from Xilinx describing how to install an RTOS on a MicroBlaze processor.
  • Getting Started with uClinux on the MicroBlaze Processor (XAPP730)
  • Getting Started with the Nucleus PLUS RTOS and EDGE Tools on the MicroBlaze Processor (XAAP1016)

Choosing a Linux OS

We will use PetaLinux from
PetaLogix. PetaLogix is an embedded Linux solution provider founded by Dr John Williams, architect and maintainer of the port of the uClinux operating system to the Xilinx MicroBlaze soft processor.

PetaLinux

PetaLogix has released PetaLinux v0.20, including Linux kernel 2.6.20 support for the Xilinx MicroBlaze soft-CPU architecture. PetaLinux is available as a free download from
http://developer.petalogix.com, along with complete documentation, getting started guides and reference designs. Pre-built demo packages for the Xilinx ML401, Spartan3E-500 and Spartan3E-1600 allow a instant preview of the capabilities of Embedded Linux on the MicroBlaze.

The "uClinux microblaze port" mailing list

John Williams has setup a mailing list where you can ask all kind of questions about uClinux and the port to MicroBlaze.

Embedded Linux developer forum

uCdot is  the place to find more information about embedded Linux.

PetaLinux system requirements

The minimum system requirements to build a PetaLinux ready hardware platform are:
  • MicroBlaze soft core processor
  • Timer
  • Interrupt Controller
  • Standard input and output devices
  • External memory controller
  • RAM (DDR-SDRAM)
  • ROM (Flash) optional
  • Microprocessor Debug Module (for image download)
PetaLinux installation procedure

Let's read the
installation guide.

Download

We will start by downloading petalinux-v0.20-rc3.tar.gz. The gzipped tar file is 317MB.

Select an installation directory

Create: mkdir /home/svenand/linux and goto the installation directory: cd /home/svenand/linux and move the tar file to this directory: mv /home/svenand/Desktop/
petalinux-v0.20-rc3.tar.gz .

Unpacking

Unzip and unpack the file using the following command: tar zxvf petalinux-v0.20-rc3.tar.gz



After unpacking the following directory structure has been generated. The total size is 1.77GB

Environment setup

To set up our PetaLinux environment, change to the PetaLinux root directory and run the set up script. This script updates our path to point to the bundled gcc toolchain, and sets the $PETALINUX environment variable to point to the PetaLinux root.

-> cd petalinux-v0.20-rc3
-> source settings.sh (bash and sh)
-> source setting.csh (csh and tcsh)

We will add the following lines to .bashrc to make sure the script will always be run:
cd
/home/svenand/linux/petalinux-v0.20-rc3
source /home/svenand/linux/petalinux-v0.20-rc3/settings.sh
cd
/home/svenand


Configure and build our Linux kernel

After we have everything setup it is time to configure and build our Linux kernel. Let's follow the
PetaLinux Platform from Scratch tutorial.

Selecting a platform

Selecting a platform is the initial step in the build of a kernel for our target. A platform configuration is essentially a collection of kernel configurations that are associated with that particular platform. This process allows the user to configure for a target platform without having to go through all the configurations associated with that platform.

Create a New Vendor Platform variant

We will use the petalinux-new-platform script to create a new vendor and platform combination for our system.

-> cd $PETALINUX/software/petalinux-dist
-> petalinux-new-platform -v Xilinx -p ML403 -k 2.6

The ML403 board has been added to the Xilinx directory.




PetaLinux kernel configuration

To start the configuration program execute the following commands:
-> cd software/petalinux-dist
-> make xconfig



Vendor/Product Selection





We select vendor Xilinx and the ML403 platform.


Kernel/Library/Defaults selection



We will use the default settings and click Save and Exit. The configuration setup is stored in the file $PETALINUX/software/petalinux-dist/.config. Later on we will change the configuration to match the hardware in our system.

Hardware modification

MicroBlaze

Instruction cache : Enabled
Data cache : Enabled

RS232 UART

Baudrate : 115200
Interrupt : Enable

Debug module

Enable the UART Interface on OPB: Disable
Interrupt : Enable

For more information about the hadware setup read the
PetaLinux Platform from Scratch tutorial.

Auto configuration

PetaLinux AutoConfig framework allows the hardware configurations to be propagated to the bootloader and Linux kernel configurations. A few simple parameters in the EDK project's MSS (MicroProcessor Software Specification) file are all that is required to automatically configure the kernel and bootloader for our specific hardware platform.

Briefly, the steps are:

  1. Create a new linux platform.
  2. Create a EDK hardware project
  3. Edit the MSS file to specifiy the PetaLinux autoconfiguration BSP tools (see below)
  4. Use XPS to build the hardware project and generate libraries and BSPs
  5. Use the petalinux-copy-autoconfig helpder script to propagate the system settings from your hardware project, across to your new Linux platform
  6. Rebuild PetaLinux, to get your fully configured bootloader, Linux kernel and root filesystem image, ready for download.
Editing the MSS file

See the PetaLinux User Guide
AutoConfig. Let' take a look in the ETC_system.mss file. This is what the OS part looks like:

BEGIN OS
 PARAMETER OS_NAME = standalone
 PARAMETER OS_VER = 1.00.a
 PARAMETER PROC_INSTANCE = microblaze_0
 PARAMETER STDIN = RS232_Uart
 PARAMETER STDOUT = RS232_Uart
END


We will change it like this:

BEGIN OS
 PARAMETER OS_NAME = petalinux
 PARAMETER OS_VER = 1.00.b
 PARAMETER PROC_INSTANCE = microblaze_0
 PARAMETER STDIN = RS232_Uart
 PARAMETER STDOUT = RS232_Uart
 PARAMETER MAIN_MEMORY = DDR_SDRAM_64Mx32
 PARAMETER MAIN_MEMORY_BANK = 0
END

Generate netlist and libraries

Let's start Xilinx Platform Studio and generate a new netlist and libraries and BSPs.
--> xps ETC_system.xmp &

The following error stops us from loading our project.

ERROR:MDT - Can not find MLD for the os petalinux 1.00.b
INFO:MDT - Directories Searched :
  - /home/svenand/root/projects/ETC/xps/bsp/petalinux_v1_00_b/data
  - /home/svenand/cad/edk91i/sw/ThirdParty/bsp/petalinux_v1_00_b/data
  - /home/svenand/cad/edk91i/sw/XilinxProcessorIPLib/bsp/petalinux_v1_00_b/data
  - /home/svenand/cad/edk91i/sw/lib/bsp/petalinux_v1_00_b/data

To fix this problem we have to find the petalinux .mld file and copy it to the XPS project directory. The .mld file can be found here: $PETALINUX/hardware/edk_user_repository/PetaLogix/bsp/petalinux_v1_00_b/data. We will make a link to the bsp directory from our EDK project directory.

-> cd $EDK_PROJECT
-> ln -s bsp
$PETALINUX/hardware/edk_user_repository/PetaLogix/bsp



We use the menu command Hardware->Generate Netlist to generate a new netlist. No configuration files are generated during the netlist generation. We then generate the libraries using the menu command Software->Generate Libraries and BSPs. This process will create the following directory structure.



Here we find the auto-config.in (Linux 2.4.x) and the Kconfig.auto (Linux 2.6.x) configuration files.


Copying the AutoConfig file

To copy the configuration file across to our currently selected PetaLinux platform, we use the petalinux-copy-autoconfig command as follows: petalinux-copy-autoconfig ETC_system.xmp

==>petalinux-copy-autoconfig ETC_system.xmp                                                               

INFO: Attempting vendor/platform auto-detect
INFO: Auto-detected Xilinx/ML403 combination.
Auto-config file successfully updated for Xilinx ML403

The script will automatically detect which platform and which Linux kernel we have specified by reading the.config file and copy the right configuration file to the right place.



Platform reconfiguration

Next we have to reconfigure the platform settings of our custom platform into PetaLinux. This step requires us to run through the following configuration options.

More to be added.

Changing the default shell

In Ubuntu 7.04 the default shell (/bin/sh) is defined as /bin/dash instead of /bin/bash. The build process script relays on the bash shell to function. To change the default shell to bash execute the following commands:

--> sudo rm -f /bin/sh
--> sudo ln -s /bin/bash /bin/sh

To change back to dash execute the following commands:

--> sudo rm -f /bin/sh
--> sudo ln -s /bin/dash /bin/sh

Adding the /tftpboot directory

When working with network-enabled embedded Linux systems, it is often convenient to update Linux images and other files over the TCP/IP network.
The directory /tftpboot is commonly used as a transfer directory for this purpose. The PetaLinux tools can optionally copy Linux and bootloader files into this (or another) directory automatically.
To create the /tftpboot directory, you must have root access.

-> sudo mkdir /tftpboot
-> sudo chmod -R 777 /tftpboot

Installing zlib1g-dev

We need zlib to be able to build the Linux kernel: sudo apt-get install zlib1g-dev

Build the 2.6 kernel and user applications

The build process
entails the following tasks.
  • Build the Linux Kernel
  • Build GNU tools
  • Build the Root Filesystem
  • Build the U-Boot bootloader

To start the build process for the newly added platform, in the $PETALINUX/software/petalinux-dist directory execute the following commands.

-> cd $PETALINUX/software/petalinux-dist

1. Build the project dependencies.
-> yes "" │ make oldconfig dep

2. Build images.
-> make all

The logfile

.......

Image Name:   PetaLinux Kernel 2.6
Created:      Sun Sep 30 17:36:28 2007
Image Type:   MicroBlaze Linux Kernel Image (uncompressed)
Data Size:    3289251 Bytes = 3212.16 kB = 3.14 MB
Load Address: 0x44000000
Entry Point:  0x44000000
# Run mkimage to build u-boot autoscr script
/home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/u-boot/tools/mkimage -A microblaze -O linux -T script -C none
    -a 0 -e 0 -n "PetaLinux Autoscr Script" 
    -d /home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/u-boot/board/petalogix/microblaze-auto/ub.config /home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/images/ub.config.img
Image Name:   PetaLinux Autoscr Script
Created:      Sun Sep 30 17:36:29 2007
Image Type:   MicroBlaze Linux Script (uncompressed)
Data Size:    1412 Bytes = 1.38 kB = 0.00 MB
Load Address: 0x00000000
Entry Point:  0x00000000
Contents:
   Image 0:     1404 Bytes =    1 kB = 0 MB
# Copy image files into /tftpboot, if requested
if [ "y" == 'y' ] ; then
        cp /home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/images/* "/tftpboot";
    fi
make[2]: Leaving directory `/home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/vendors/Xilinx/ML401'
make[1]: Leaving directory `/home/svenand/linux/petalinux-v0.20-rc3/software/petalinux-dist/vendors'
==>   

Congratulations to all of us. We made it!!!!

Output images


Once the build process is completed, all the images are located in both the $PETALINUX/software/petalinux-dist/images and the /tftpboot directory.


tftpboot directory content





Image Name
Description File Size
Linux Kernel
   
image.bin The Linux kernel and root filesystem image in binary format
3.1 MB
image.elf The Linux kernel and root filesystem image in ELF format 3.4 MB
image.srec The Linux kernel and root filesystem image in SREC format
9.3 MB
image.ub The Linux kernel and root filesystem image in U-Boot format 3.1 MB
linux.bin  ?? 1.9 MB
romfs.img The ROMFS image in binary format
1.2 MB 
 U-Boot    
 u-boot.bin The U-Boot image in binary format
119 KB
 u-boot.srec The U-Boot image in SREC format 358 KB
 u-boot-s.bin The relocatable U-Boot image in binary format 119 KB 
 u-boot-s.elf The relocatable U-Boot image in ELF format 120 KB 
 u-boot-s.rec The relocatable U-Boot image in SREC format 358 KB
 ub.config.img U-Boot platform configuration script in binary format
1.4 KB



Top  Next   Previous




Posted at 07:20 am by svenand
Comments (2)  

 
Sep 1, 2007
Writing a blog
Some of you have asked me why I didn't write a book instead of this blog. Here are a few reasons:

Time to market

It takes 10 minutes to setup a blog account at one of the many companies offering blog services. It may take a year to have a book published.

Simplicity

You can start from day one writing your blog. You don't have know anything about web design or html. Write the text and click publish. It is that easy.

Flexibility

You have a lot of freedom when designing your blog. You can use any font style and font size you like. There are hundreds of page designs you can choose from and if you don't like them you can design one yourself. You can add as many images you like and you can link to other web pages and documents.

Extend and update

At any time you can introduce more information to your blog, fix mistakes and add updates.

Interaction

A blog is the best way to interact with your readers. They can ask questions and add comments and you can answer and make comments.

Presence/Exposure

This blog can be read all over the world. The only thing you need is a computer and an internet connection.


And here is one reason for not writing a blog:

No food on the table

Writing a blog doesn't bring food on the table. You have to find a way to make some money out of your blog.


Posted at 07:19 am by svenand
Comments (2)  

 
Aug 27, 2007
FPGA design from scratch. Part 42
Adding a timer

Before we can install a Linux OS in our embedded system we have to add a timer IP. Now when we know how to add a new peripheral it will only take us a few minutes. We start by selecting the OPB Timer Counter from the IP catalog.




We add it and configure it.



We generate addresses and connect the ports and we are done.

Connect the interrupt signal

We will add the interrupt signal coming from the timer/counter to the interrupt controller. We give the highest priority to the timer interrupt. Select the Ports display and click the first port to display this window.






OPB Timer/Counter


The
OPB Timer/Counter is a 32-bit timer module that attaches to the OPB (On-Chip Peripheral Bus). It includes two programmable interval timers with interrupt, event generation, and event capture capabilities. It also includes a Pulse Width Modulator (PWM) output and a configurable counter width. Each of the two timer modules is capable of holding the initial value of the counter for event generation or capture a value based on the mode of the timer.

                                                                                                                                               
(Courtesy of Xilinx)

Register address map

Register Name
Abbreviation OPB Offset
Type
Control/Status Register 0
TSCR0 0x00 R/W
Load Register 0
TLR0 0x04 R/W
Timer/Counter Register 0
TCR0 0x08 R
Control/Status Register 1
TSCR1 0x10 R/W
Load Regster 1
TLR1 0x14 R/W
Timer/Counter Register 1
TCR1 0x18 R

The registers are organized as big-endian data.

Library Generation


After running libgen we have copied the following source files to the libsrc directory.




xparameters.h

/* Definitions for driver TMRCTR */
#define XPAR_XTMRCTR_NUM_INSTANCES 1

/* Definitions for peripheral OPB_TIMER_0 */
#define XPAR_OPB_TIMER_0_BASEADDR 0x43505000
#define XPAR_OPB_TIMER_0_HIGHADDR 0x435050FF
#define XPAR_OPB_TIMER_0_DEVICE_ID 0


xtmrctr_l.h


/************************** Constant Definitions *****************************/

/**
 * Defines the number of timer counters within a single hardware device. This
 * number is not currently parameterized in the hardware but may be in the
 * future.
 */
#define XTC_DEVICE_TIMER_COUNT    2

/* Each timer counter consumes 16 bytes of address space */

#define XTC_TIMER_COUNTER_OFFSET 16

/** @name Register Offset Definitions
 * Register offsets within a timer counter, there are multiple
 * timer counters within a single device
 * @{
 */

#define XTC_TCSR_OFFSET      0     /**< control/status register */
#define XTC_TLR_OFFSET       4     /**< load register */
#define XTC_TCR_OFFSET       8     /**< timer counter register */


/** @name Control Status Register Bit Definitions
 * Control Status Register bit masks
 * Used to configure the timer counter device.
 * @{
 */

#define XTC_CSR_ENABLE_ALL_MASK     0x00000400  /**< Enables all timer counters */
#define XTC_CSR_ENABLE_PWM_MASK     0x00000200  /**< Enables the Pulse Width
                                                     Modulation */
#define XTC_CSR_INT_OCCURED_MASK    0x00000100  /**< If bit is set, an interrupt has
                                                     occured.*/
                                                /**< If set and '1' is written
                                                     to this bit position,
                                                     bit is cleared. */
#define XTC_CSR_ENABLE_TMR_MASK     0x00000080  /**< Enables only the specific timer */
#define XTC_CSR_ENABLE_INT_MASK     0x00000040  /**< Enables the interrupt output. */
#define XTC_CSR_LOAD_MASK           0x00000020  /**< Loads the timer using the load
                                                     value provided earlier in the
                                                     Load Register, XTC_TLR_OFFSET. */
#define XTC_CSR_AUTO_RELOAD_MASK    0x00000010  /**< In compare mode, configures the
                                                     timer counter to reload from the
                                                     Load Register. The default mode
                                                     causes the timer counter to hold
                                                     when the compare value is hit. In
                                                     capture mode, configures the
                                                     timer counter to not hold the
                                                     previous capture value if a new
                                                     event occurs. The default mode
                                                     cause the timer counter to hold
                                                     the capture value until
                                                     recognized. */
#define XTC_CSR_EXT_CAPTURE_MASK    0x00000008  /**< Enables the external input to
                                                     the timer counter. */
#define XTC_CSR_EXT_GENERATE_MASK   0x00000004  /**< Enables the external generate
                                                     output for the timer. */
#define XTC_CSR_DOWN_COUNT_MASK     0x00000002  /**< Configures the timer counter to
                                                     count down fromstart value, the
                                                     default is to count up. */
#define XTC_CSR_CAPTURE_MODE_MASK   0x00000001  /**< Enables the timer to capture the
                                                     timer counter value when the
                                                     external capture line is asserted.
                                                     The default mode is compare mode.*/


Application program

We have taken the application program from the examples directory found in the EDK installation (
..../edk91i/sw/XilinxProcessorIPLib/drivers/tmrctr_v1_00_b/examples).

XStatus TmrCtrLowLevelExample(Xuint32 TmrCtrBaseAddress, Xuint8 TmrCtrNumber)
{
    Xuint32 Value;
    Xuint32 ControlStatus;
    Xuint32 i;


   /*
     * Set the master enable bit and enable hardware interrupts. We must set the
      * master enable bit before enabling interrupts otherwise we will get a spurious interrrupt (IRQ goes high) ???
     */
    XIntc_Out32(XPAR_OPB_INTC_0_BASEADDR + XIN_MER_OFFSET, XIN_INT_MASTER_ENABLE_MASK | XIN_INT_HARDWARE_ENABLE_MASK);
 

    /*
     * Enable interrupts from the timer/counter and the ETC
    */
    XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, XPAR_OPB_TIMER_0_INTERRUPT_MASK | XPAR_ETC_0_O_INTERRUPT_MASK);
 
    /*
     * Clear the Timer Control Status Register
     */
    XTmrCtr_mSetControlStatusReg(TmrCtrBaseAddress, TmrCtrNumber,0x0);

    /*
     * Set the value that is loaded into the timer counter and cause it to
     * be loaded into the timer counter
     */
    XTmrCtr_mSetLoadReg(TmrCtrBaseAddress, TmrCtrNumber, 0x100);
    XTmrCtr_mLoadTimerCounterReg(TmrCtrBaseAddress, TmrCtrNumber);

    /*
     * Clear the Load Timer bit in the Control Status Register
     */
    ControlStatus = XTmrCtr_mGetControlStatusReg(TmrCtrBaseAddress,
                                                 TmrCtrNumber);
    /*
     * Setup the counter to count down and enable interrupt when counter rolls over
    */

    XTmrCtr_mSetControlStatusReg(TmrCtrBaseAddress, TmrCtrNumber,
                                 ControlStatus & (~XTC_CSR_LOAD_MASK)| XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_ENABLE_INT_MASK);


    /*
     * Start the timer counter such that it's decrementing.
     */

    XTmrCtr_mEnable(TmrCtrBaseAddress, TmrCtrNumber);

    /*
     * Read the value of the timer counter and wait for an interrupt
     */

   
while (1)
     {
        /*
         * If the interrupt occurred which is indicated by the global
         * variable which is set in the device driver handler, then
         * stop waiting
         */
        Value = XTmrCtr_mGetTimerCounterReg(TmrCtrBaseAddress, TmrCtrNumber);
        if (InterruptProcessed)
        {
            break;
        }
    }


   /*

     * Disable the timer counter such that it stops incrementing
     */

    XTmrCtr_mDisable(TmrCtrBaseAddress, TmrCtrNumber);

    return XST_SUCCESS;
}

Simulation results

The counter will count down from 0x100 (256 decimal) to 0, when an interrupt will be generated. It takes 2590 ns from starting the timer to when the interrupt is generated. Clock frequency is 100 MHz (256*10 ns = 2560 ns).




Top  Next  Prevoius



Posted at 07:14 am by svenand
Make a comment  

 
Aug 20, 2007
FPGA design from scratch. Part 41
Adding an interrupt controller

The ETC will generate an interrupt when the test has finished, if enabled (see Simvision plot). Instead of waiting a fixed time for the test to complete we could use the interrupt signal to tell the application program that the test has finished. Sounds like a good idea. Let's implement an interrupt controller to handle our interrupt. The MicroBlaze processor can handle one interrupt but we will probably have more than one interrupt in our final system.



Finding an interrupt controller

Let's try the
Xilinx IP center and see what we find. The first thing I found was an application note, XAPP778 Using and Creating Interrupt-Based Systems.

As it says in the Xilinx documentation:
This application note describes how to properly set up external and internal interrupts in an
embedded hardware system. Use of an interrupt controller to manage more than one interrupt
is also included. The application note discusses the software use model, including initializing
the interrupt controller and peripherals, registering the interrupt handlers, and enabling
interrupts.

Here is a definition of an interrupt taken from this application note:
Interrupts are automatic control transfers that occur as a result of an exception. An interrupt
occurs when the processor suspends execution of a program after detecting an exception. The
processor saves the suspended-program machine state and a return address into the
suspended program. This information is stored in a pair of special registers, called save/restore
registers. A predefined machine state is loaded by the processor, which transfers control to an
interrupt handler. An interrupt handler is a system-software routine that responds to the
interrupt, often by correcting the condition causing the exception. System software places
interrupt handlers at predefined addresses in physical memory and the interrupt mechanism
automatically transfers control to the appropriate handler based on the exception condition.


Because the MicroBlaze core only supports one external interrupt, designs which require more than one interrupt, must include an
OPB Interrupt Controller (OPB_INTC).

                                                                                                                                      
(Courtesy of Xilinx)

OPB_INTC



                                                                                                                                       (Courtesy of Xilinx)
Register map

Register Name
Abbreviation OPB Offset
Interrupt Status Register
ISR  0 (0x00)
Interrupt Pending Register
IPR  4 (0x04)
Interrupt Enable Register
IER  8 (ox08)
Interrupt Acknowledge Register
IAR 12 (0x0c) 
Set Interrupt Enable Bits
SIE 16 (0x10)
Clear Interrupt Enable Bits
CIE 20 (0x14)
Interrupt Vector Register
IVR 24 (0x18)
Master Enable Register
MER 28 (0x1c)



We will use Xilinx Platform Studio and add the IP. For more information about adding an IP read
Part 17 and Part 31 of this tutorial.




Configuring the interrupt controller

Right-click the opb_intc_0 entry in the System Assembly View and select Configure IP. It seems we don't have to configure anything. Everything is auto computed.






Making connections

We select Ports in the System Assembly View and click the plus sign to display the ports available in opb_intc_0.



We connect the IRQ output of the interrrupt controller to the interrupt input on MicroBlaze and we are done with the hardware setup. The rest is software.




Software setup

After running library generation (libgen) the intc_v1_00_c software device driver has been added to the libsrc directory. The source code has been compiled and stored in the libxil.a library.



xparameters.h

The following parameters have been added to xparameters.h:

#define XPAR_INTC_MAX_NUM_INTR_INPUTS 1
#define XPAR_XINTC_HAS_IPR 1
#define XPAR_XINTC_USE_DCR 0
/* Definitions for driver INTC */
#define XPAR_XINTC_NUM_INSTANCES 1

/* Definitions for peripheral OPB_INTC_0 */
#define XPAR_OPB_INTC_0_BASEADDR 0x43505000
#define XPAR_OPB_INTC_0_HIGHADDR 0x4350503F
#define XPAR_OPB_INTC_0_DEVICE_ID 0
#define XPAR_OPB_INTC_0_KIND_OF_INTR 0x00000001


/******************************************************************/

#define XPAR_INTC_SINGLE_BASEADDR 0x43505000
#define XPAR_INTC_SINGLE_HIGHADDR 0x4350503F
#define XPAR_INTC_SINGLE_DEVICE_ID XPAR_OPB_INTC_0_DEVICE_ID
#define XPAR_ETC_0_O_INTERRUPT_MASK 0X000001
#define XPAR_OPB_INTC_0_ETC_0_O_INTERRUPT_INTR 0

/******************************************************************/

xintc_l.h

#define XIN_ISR_OFFSET      0       /* Interrupt Status Register */
#define XIN_IPR_OFFSET      4       /* Interrupt Pending Register */
#define XIN_IER_OFFSET      8       /* Interrupt Enable Register */
#define XIN_IAR_OFFSET      12      /* Interrupt Acknowledge Register */
#define XIN_SIE_OFFSET      16      /* Set Interrupt Enable Register */
#define XIN_CIE_OFFSET      20      /* Clear Interrupt Enable Register */
#define XIN_IVR_OFFSET      24      /* Interrupt Vector Register */
#define XIN_MER_OFFSET      28      /* Master Enable Register */

/* Bit definitions for the bits of the MER register */

#define XIN_INT_MASTER_ENABLE_MASK      0x1UL
#define XIN_INT_HARDWARE_ENABLE_MASK    0x2UL /* once set cannot be cleared */

Generate a software interrupt

Here is an example of a c-program to setup the interrupt controller and to generate a software interrupt. We will use the software interrupt to test our interrupt handling routine. When we are satisfied, we will enable the hardware interrupt and at the same time disable all further software interrupts.

     /*
     * Enable interrupts for all devices that cause interrupts.
     * Write to Interrupt Enable Register
     */
    XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, XPAR_ETC_0_O_INTERRUPT_MASK);


    /*
     * Set the master enable bit. Note that we do not enable hardware
     * interrupts yet since we want to simulate an interrupt from software
     * down below. WRite to Master Enable Register
     */
    XIntc_Out32(XPAR_OPB_INTC_0_BASEADDR + XIN_MER_OFFSET, XIN_INT_MASTER_ENABLE_MASK);

    /*
     * This step is processor specific, connect the handler for the interrupt
     * controller to the interrupt source for the processor. Will be added later on.
     */
    // SetupInterruptSystem();

    /*
     * Cause (simulate) an interrupt so the handler will be called. This is
     * done by writing a 1 to the interrupt status bit for the device interrupt.
     * Write to Interrupt Status Register
     */
    XIntc_Out32(XPAR_OPB_INTC_0_BASEADDR + XIN_ISR_OFFSET, XPAR_ETC_0_O_INTERRUPT_MASK);
   

Here is an Simvision plot from our simulation. We can see that the irq output signal from the interrrupt controller goes high indicating an interrupt request.





Generate a hardware interrupt

Here is an example of a c-program to setup the interrupt controller and to generate a hardware interrupt.

     /*
     * Enable interrupts for all devices that cause interrupts.
     * Write to Interrupt Enable Register
     */
    XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, XPAR_ETC_0_O_INTERRUPT_MASK);


    /*
     * Set the master enable bit. Enable hardware interrupts.
     * Write to Master Enable Register
     */
    XIntc_Out32(XPAR_OPB_INTC_0_BASEADDR + XIN_MER_OFFSET, XIN_INT_MASTER_ENABLE_MASK | XIN_INT_HARDWARE_ENABLE_MASK);

    /*
     * This step is processor specific, connect the handler for the interrupt
     * controller to the interrupt source for the processor. Will be added later on.
     */
    // SetupInterruptSystem();

     /*
     * Wait for the interrupt to be processed, if the interrupt does not
     * occur this loop will wait forever
     */
    while (1)
    {
        /*
         * If the interrupt occurred which is indicated by the global
         * variable which is set in the device driver handler, then
         * stop waiting
         */
        if (InterruptProcessed)
        {
            break;
        }
    }
 


Here is an Simvision plot from our simulation. We can see that the irq output signal from the interrrupt controller goes high after the ETC_INTERRUPT signal goes high, indicating a hardware interrupt request.






MicroBlaze interrupt handling

As it says in the Xilinx documentation:
The MicroBlaze processor supports one external interrupt source via a connection to the
Interrupt input port. The processor will only react to interrupts if the interrupt enable (IE) bit in
the machine status register (MSR) is set to 1. On an interrupt the instruction in the execution
stage will complete, while the instruction in the decode stage is replaced by a branch to the
interrupt vector (address 0x10). The interrupt return address (the PC associated with the
instruction in the decode stage at the time of the interrupt) is automatically loaded into general
purpose register R14.
In addition the processor also disables future interrupts by clearing the IE bit in the MSR. In
order for an Interrupt to interrupt the currently executing Interrupt, the interrupt handler code
must re-enable interrupts. If an OPB_INTC controller has been utilized, the INTC driver code
must be modified to re-enable interrupts.
The processor ignores interrupts, if the break in progress (BIP) bit in the MSR register is set to 1.

Enable MicroBlaze interrupt handling

We will use the following c-program function to enable MicroBlaze interrupt handling:  microblaze_enable_interrupts();

MicroBlaze interrupt timing

This Simvision plot shows the MicroBlaze interrupt handling. It takes 70ns from when the ETC generates an interrupt until the MicroBlaze processor  reacts.






Top 
Next  Previous



Posted at 01:59 pm by svenand
Make a comment  

 
Aug 15, 2007
FPGA design from scratch. Part 40
Debugging our hardware design

We have seen earlier how we can debug our software using Xilinx Microprocessor Debugger (XMD). Now let's see how we can debug our hardware. We could of course go out and buy an
oscilloscope, a logic analyzer and voltmeter and hook them up to our development board. This is both expensive and complicated and it still wouldn't be possible to connect to internal nodes in the FPGA. A better solution is to use ChipScope Pro.

ChipScope Pro

As it says in the Xilinx documentation:
ChipScope™ Pro inserts logic analyzer, bus analyzer, and Virtual I/O low-profile software cores directly into your design, allowing you to view any internal signal or node, including embedded hard or soft processors. Signals are captured at or near operating system speed and brought out through the programming interface, freeing up pins for your design. Captured signals can then be analyzed through the included ChipScope Pro Logic Analyzer.

Here is document giving a glance of ChipScope Pro.

ChipScope Pro eliminates the traditional ASIC problems:
  •     I Can't get internal access to signals in my hard IP"
  •     Full scan insertion increases overhead"
  •     How do I access the embedded system bus?"
  •     It's too late – I can't afford a design re-spin!"
  •     Co-Verification tools are cumbersome and slow with complex issues"
  •     I need to debug my design at full system speed"
Trying out ChipScope Pro

ChipScope Pro costs 700USD to buy but we can get a 60 days evaluation license from Xilinx for free. Click "Evalaute ChipScope" to get a license and to download a copy of ChipScope Pro 9.2i from the
Xilinx download center.




ChipScope installation

To install the ChipScope program we first unzip the downloaded file and store the archive in a temporary directory. We run the setup script file to install ChipScope in a directory we choose. In our case /home/svenand/cad/chipscope_9.2i.




Here is the installed directory structure for ChipScope.



Using ChipScope

I'll be back with more information on how to implement and use ChipScope. Stayed tuned.


Top  Previous  Next




Posted at 02:44 pm by svenand
Make a comment  

 
Aug 12, 2007
FPGA design from scratch. Part 39
Fixing our software device driver

Let's modify our template files and start with the .tcl file.

etc_v2_1_0.tcl

The .tcl script file copies the parameters we specify to the xparameters.h and xextc_g.c files during library generation. It looks like this after modifications.

proc generate {drv_handle} {
  set level [xget_value $drv_handle "PARAMETER" "level"]
  xdefine_include_file $drv_handle "xparameters.h" "XEtc" "NUM_INSTANCES" "MEM_BANK0_BASE_ADDR" "MEM_BANK0_HIGH_ADDR" "MEM_BANK1_BASE_ADDR" "MEM_BANK1_HIGH_ADDR" "REGISTER_BASE_ADDR" "REGISTER_HIGH_ADDR" "DEVICE_ID" "C_INTERRUPT_PRESENT"
  xdefine_config_file $drv_handle "xetc_g.c" "XEtc"  "DEVICE_ID" "MEM_BANK0_BASE_ADDR" "MEM_BANK1_BASE_ADDR" "REGISTER_BASE_ADDR" "C_INTERRUPT_PRESENT"
}

This is the result taken from the xparameters.h file.

/* Definitions for driver ETC */
#define XPAR_XETC_NUM_INSTANCES 1

/* Definitions for peripheral ETC_0 */
#define XPAR_ETC_0_MEM_BANK0_BASE_ADDR 0x42a08000
#define XPAR_ETC_0_MEM_BANK0_HIGH_ADDR 0x42a08fff
#define XPAR_ETC_0_MEM_BANK1_BASE_ADDR 0x42a09000
#define XPAR_ETC_0_MEM_BANK1_HIGH_ADDR 0x42a09fff
#define XPAR_ETC_0_REGISTER_BASE_ADDR 0x71A00000
#define XPAR_ETC_0_REGISTER_HIGH_ADDR 0x71A0001F
#define XPAR_ETC_0_DEVICE_ID 0
#define XPAR_ETC_0_INTERRUPT_PRESENT 0

etc_v2_1_0.tcl.mdd

The .mdd file looks like this.
The "copyfiles" line instructs the EDK tools to copy the source files into the user's project directory and compile them from there.

OPTION psf_version = 2.1;

BEGIN driver etc

  OPTION supported_peripherals = (ETC_0);
  OPTION driver_state = ACTIVE;
  OPTION depends = (common_v1_00_a);
  OPTION copyfiles = all;

 BEGIN INTERFACE linux
 END INTERFACE

 BEGIN ARRAY interrupt_handler
 END ARRAY

END driver



Makefile

In the Makefile we have to add all header file under INCLUDEFILES. This will copy the header files to the directory include during library generation.

COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a

RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}

INCLUDEFILES=xetc.h xetc_l.h xetc_i.h

LIBSOURCES=*.c
OUTS = *.o


xetc_g.c


The xetc_g.c is automatically generated by Libgen. Here is the configuration table taken from the xetc_g.c file.


/*
* The configuration table for devices
*/

XEtc_Config XEtc_ConfigTable[] =
{
    {
        XPAR_ETC_0_DEVICE_ID,
        XPAR_ETC_0_MEM_BANK0_BASE_ADDR,
        XPAR_ETC_0_MEM_BANK1_BASE_ADDR,
        XPAR_ETC_0_REGISTER_BASE_ADDR,
        XPAR_ETC_0_INTERRUPT_PRESENT
    }

xetc.h

The following type definition are modified to match with the configuration table shown above.


/**
 * This typedef contains configuration information for the device.
 */
typedef struct
{
    Xuint16  DeviceId;          /* Unique ID  of device */
    Xuint32  Mem0_BaseAddress;  /* Memory bank0 base address */
    Xuint32  Mem1_BaseAddress;  /* Memory bank1 base address */
    Xuint32  Reg_BaseAddress;   /* Register bank base address */
    Xboolean InterruptPresent;  /* Are interrupts supported in h/w */
} XEtc_Config;

/**
 * The XEtc driver instance data. The user is required to allocate a
 * variable of this type for every ETC device in the system. A pointer
 * to a variable of this type is then passed to the driver API functions.
 */
typedef struct
{
    Xuint32  Mem0_BaseAddress;  /* Memory bank0 base address */
    Xuint32  Mem1_BaseAddress;  /* Memory bank1 base address */
    Xuint32  Reg_BaseAddress;   /* Register bank base address */
    Xuint32  IsReady;           /* Device is initialized and ready */
    XEtc_Config *ConfigPtr;     /* Pointer to the configuration */
} XEtc;

xetc_l.h

For the lowest level we only need to provide register read an write functions. We will use the Xilinx standard routines XIo_Out32 and XIo_in32 to give us these functions.

/****************************************************************************/
#define XEtc_mWriteReg(BaseAddress, RegOffset, Data) XIo_Out32((BaseAddress) + (RegOffset), (Xuint32)(Data))

/****************************************************************************/
#define XEtc_mReadReg(BaseAddress, RegOffset)  XIo_In32((BaseAddress) + (RegOffset))

The XIo_Out32 and XIo_In32 are defined in the header file xio.h found in the include directory.

* Performs an input operation for a 32-bit memory location by reading from the
* specified address and returning the value read from that address.
*
* @param    InputPtr contains the address to perform the input operation at.
*
* @return   The value read from the specified input address.
*

#define XIo_In32(InputPtr)  (*(volatile Xuint32 *)(InputPtr))


* Performs an output operation for a 32-bit memory location by writing the

* specified value to the the specified address.
*
* @param    OutputPtr contains the address to perform the output operation at.
* @param    Value contains the value to be output at the specified address.
*
* @return   None.
*

#define XIo_Out32(OutputPtr, Value) (*(volatile Xuint32 *)((OutputPtr)) = (Value))


Writing an application program

We will start out writing a low level application program only using the read/write functions. Here is an example:

//$$INCLUDE
/*************************************************************************/
/*                                                                       */
/*                     I N C L U D E   H E A D E R   F I L E S           */
/*                                                                       */
/*************************************************************************/

#include "xparameters.h"
#include "xetc.h"
#include "xetc_l.h"
#include "xutil.h"
#include <stdio.h>


//$$DEFINE
/*************************************************************************/
/*                                                                       */
/*                       D E F I N E   C O N S T A N T S                 */
/*                                                                       */
/*************************************************************************/

// The following constant maps to the name of the hardware instances that
// were created in the EDK XPS system.

#define  ETC_REG_BASEADDR      XPAR_ETC_0_REGISTER_BASE_ADDR
 
// The following parameters are used to setup the ETC
#define  ENABLE_INTERRUPT      0X1000
#define  DISABLE_INTERRUPT     0X0
#define  ENABLE_LOOP_MODE      0x800
#define  DISABLE_LOOP_MODE     0x0
#define  SKIP_TDO_SHIFTIR      0x200
#define  SKIP_TDO_SHIFTDR      0x400
#define  DISABLE_SINGLE_STEP   0x0
#define  ENABLE_SINGLE_STEP    0x100
#define  DISABLE_TCK           0x0
#define  ENABLE_TCK            0x80
#define  CLOCK_RATE_DIV_BY_4   0x0
#define  CLOCK_RATE_DIV_BY_8   0x10
#define  CLOCK_RATE_DIV_BY_16  0x20
#define  CLOCK_RATE_DIV_BY_32  0x30
#define  CLOCK_RATE_DIV_BY_64  0x40
#define  EXTERNAL_TEST         0x8

#define  START_ETC             0x1
#define  STOP_ETC              0x0

//$$FUNCTIONS
/*************************************************************************/
/*                                                                       */
/*                       D E F I N E   F U N C T I O N S                 */
/*                                                                       */
/*************************************************************************/

void usleep(unsigned int useconds)
{
  int i,j;
  for (j=0;j<useconds;j++)
    for (i=0;i<26;i++) asm("nop");
}

//$$ETC TEST PROGRAM
/*************************************************************************/
/*                                                                       */
/*                     E T C   T E S T  P R O G R A M                    */
/*                                                                       */
/*************************************************************************/


// Define testprogram

// TestResetKeepingTrstzLow (10);
// LoadInstruction(INSTRUCTION_LENGTH,IDCODE);
// ReadWriteDataRegister(IdentificationRegLen+20,{{IdentificationRegLen{1'b0}},20'b1110011101});
// SetExpectedData(IdentificationRegLen+20,{20'b1110011101,{IdentificationRegLen{1'bx}}});
// EndOfTestProgram;

 Xuint32 TestProgram[] = {

     
  0x800000a1,
  0xc0000043,
  0x00000002,
  0xc0340004,
  0x4000039d,
  0x00000000,
  0x8000000c };
 
  int  ProgramSize =  7;


//$$MAIN
/*************************************************************************/
/*                                                                       */
/*                        M A I N   P R O G R A M                        */
/*                                                                       */
/*************************************************************************/


int main(void) {

    int               i;
    Xuint32  StatusReg;
   
    print("Load test program ");
   
    // Load test program to test program RAM
    for (i = 0; i < ProgramSize; i++) {
           XEtc_mWriteReg(XPAR_ETC_0_MEM_BANK0_BASE_ADDR, i*4, TestProgram[i]);   
    };

    // Write to control register
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_CONTROL_REG_OFFSET,
        DISABLE_INTERRUPT +
        DISABLE_LOOP_MODE +
        SKIP_TDO_SHIFTIR +
        DISABLE_SINGLE_STEP +
        ENABLE_TCK +
        CLOCK_RATE_DIV_BY_4 +
        EXTERNAL_TEST);
   
    print("Start test ");
    // Start test
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_EXECUTE_REG_OFFSET,
        START_ETC);
 
   // Wait for test to finish
   usleep(4);

    print("Stop test ");
    // Stop test
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_EXECUTE_REG_OFFSET,
        STOP_ETC);
       
    // Stop TCK
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_CONTROL_REG_OFFSET,
        DISABLE_INTERRUPT +
        DISABLE_LOOP_MODE +
        SKIP_TDO_SHIFTIR +
        DISABLE_SINGLE_STEP +
        DISABLE_TCK +
        CLOCK_RATE_DIV_BY_4 +
        EXTERNAL_TEST);

   // Read status register
   print("Read status register ");  
   StatusReg = XEtc_mReadReg(ETC_REG_BASEADDR, XETC_STATUS_REG_OFFSET);
   xil_printf("Status reg : %x ",StatusReg);


   return 0;
   
    }

Print statements

To save memory space we don't use the standard print routines like printf. Instead we use <xil_printf>and <print>.  


Printout from program

After compiling and linking the program we download it to our design. The program starts and prints out the following text:

Load test program
Start test
Stop test
Read status register
Status reg : 3464


The value in the status register tells us that the testprogram ran successfully. We have written our first application program to drive the ETC. One more milestone reached.


Generate HDL simulation files

We can use the following command from the commandline to generate the HDL simulation files.

==> cd /home/svenand/root/projects/ETC/xps
==> simgen -f simgen.opt

Here is the output:

Simulation Model Generator
Xilinx EDK 9.1.01 EDK_J_SP1.3
Copyright (c) 1995-2007 Xilinx, Inc.  All rights reserved.
Command Line: simgen -p xc4vfx12ff668-10 -lang vhdl -pe microblaze_0
SDK_projects/ETC_system_program/Debug/ETC_system_program.elf -mixed yes -s ncs
-tb -X /home/svenand/root/projects/ETC/verification/database/ncsim/macrolib/ -E
/home/svenand/root/projects/ETC/verification/database/ncsim/edklib/ -m
behavioral ETC_system.mhs

MHS file              : /home/svenand/root/projects/ETC/xps/ETC_system.mhs
Language (-lang)      : VHDL
Simulation Model (-m) : Behavioral
Simulator (-s)        : NcSim (NCS)
Part (-p) [ family ]  : xc4vfx12ff668-10 [ virtex4 ]
Output directory (-od): /home/svenand/root/projects/ETC/xps/

Edklib (-E) :
/home/svenand/root/projects/ETC/verification/database/ncsim/edklib/
Xlib (-X)   :
/home/svenand/root/projects/ETC/verification/database/ncsim/macrolib/

..........

Analyzing file
/home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf...
INFO:MDT - BRAM lmb_bram will be initialized with ELF of processor microblaze_0
Running Data2Mem with the following command:
data2mem -bm ETC_system_sim.bmm  -bd
/home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf tag microblaze_0  -u  -o u tmpucf.ucf

Generating simulator compile script ...

Generating the BRAM initialization file

If we only changed the application program file (.elf) we don't have to generate all the HDL simulation files. We only need the BRAM initialization file:  ETC_system_init.vhd. This file can generated in these two steps:
  1. Use data2mem to convert the .elf file to a .ucf file
  2. Use ucf2vhdl.pl to convert the .ucf file to a .vhdl file
==> cd /home/svenand/root/projects/ETC/xps/simulation/behavioral

==> data2mem -bm ETC_system_sim.bmm  -bd /home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf tag microblaze_0  -u  -o u tmpucf.ucf

==> xilperl /home/svenand/cad/edk91i/bin/lin/ucf2vhdl.pl tmpucf.ucf ETC_system_init.vhd ETC_system ETC_system_conf vhdl

Running a simulation

Here is the same application program running in a simulation.




Top  Next  Previous



Posted at 08:56 am by svenand
Make a comment  

 
Aug 1, 2007
Parallels versus VMware
How good is our virtual machine and is there a difference between Parallels Desktop and VMware Fusion when it comes to execution speed. Let's find out.  We will benchmark the two. Here is what we have.

Hardware

MacBook Intel Core 2 Duo. 2.0 GHz with 1Gb of memory.

Host software

Mac OS X 10.4.10 and the virtual machines Parallels Desktop 3.0 and VMware Fusion 1.0.


Virtual machine software

Ubuntu Linux 7.04 Feisty


Virtual machine setup

512 Mb of memory. One virtual CPU.

Applications


We will use the following Xilinx FPGA tools in our benchmark.
The netlist generation tool runs the Xilinx tool XST to synthesis a complete FPGA design. The bitstream generation tool does the  place and route of the whole design and generates the bitstream to configure the FPGA. Both tools are very compute intensive, using more than 90% of the processor time.


Result

 Task Execution time [s]
Parallels Desktop
Execution time [s]
VMware Fusion
 Netlist generation
 585  556
 Bitstream generation
 255  245


Conclusion


The difference between the two virtual machines is very small and that is what we expected. This benchmark is not very comprehensive and should not be used as a deciding factor.






Posted at 10:41 pm by svenand
Make a comment  

 
Jul 12, 2007
FPGA design from scratch. Part 38

Writing software for our embedded system

I think we are ready to start writing some software to drive our embedded test controller. To make the application software easier to write and understand we will first come up with a software device driver for the ETC.

Writing a software device driver

As it says in the Xilinx Documentation:
Many of you have used embedded microprocessors in your recent FPGA designs. Some of you are experienced embedded processor users, and some of you are beginners to this method of design in FPGAs. Most embedded processor designers will at some stage decide that they need to incorporate a block of custom hardware into the processor system and then control it from software running on the processor. This is often a daunting task, and one that causes much confusion to the designer. This TechXclusive takes a step-by-step approach to designing a custom peripheral for use in an embedded processor system, then looks at some more advanced topics, including writing software device drivers for the created peripheral.


Software development overview

The embedded software platform defines, for each processor, the drivers associated with the peripherals we include in our hardware platform (the board support package), selected libraries, standard input/output devices, interrupt handler routines, and other related software features. Your Xilinx Platform Studio (XPS) project further defines software applications to run on each processor, which are based on the software platform.

Device Driver Programmer Guide

The purpose of this document is to describe the Xilinx device driver environment. This includes the device driver architecture, the
Application Programmer Interface (API) conventions, the scheme for configuring the drivers to work with reconfigurable hardware devices, and the infrastructure that is common to all device drivers.
This document is intended for the software engineer that is using the Xilinx device drivers. It contains design and implementation details necessary for using the drivers. The guide can be found here: EDK_install_dir/doc/usenglish/xilinx_drivers_guide.pdf and in html format :
EDK_install_dir/doc/usenglish/xilinx_drivers.htm

We will use this guide and the TechXclusive to help us write a device driver for the ETC peripheral.

Platform Specification Format Reference Manual

EDK tools are designed to operate in a data-driven manner. There are various meta-data files that capture information, for example, about various IPs, drivers, and software libraries being used in the EDK tools. Files are also used to capture both hardware and software aspects of our design information. These are ASCII files. The set of all these meta-data formats is referred to as the
Platform Specification Format or PSF.

Microprocessor Driver Definition (MDD)

An MDD file contains directives for customizing software drivers. Each device driver has an MDD file and a Tcl (Tool Command Language) file associated with it. The MDD file is used by the Tcl file to customize the driver, depending on different options configured in the MSS file.

Libraries and driver generation

As it says in the Xilinx Documentation:
The MHS and the MSS files define a system. For each processor in the system, Libgen finds the list of addressable peripherals. For each processor, a unique list of drivers and libraries are built. Libgen does the following for each processor:
  • Builds the directory structure as shown here below.
  • Copies the necessary source files for the drivers, OSs, and libraries into the processor instance specific area: OUTPUT_DIR/processor_instance_name/libsrc.
  • Calls the design rule check (defined as an option in the MDD or MLD file) procedure for each of the drivers, OSs, and libraries visible to the processor.
  • Calls the generate Tcl procedure (if defined in the Tcl file associated with an MDD or MLD file) for each of the drivers, OSs, and libraries visible to the processor. This generates the necessary configuration files for each of the drivers, OSs, and libraries in the include directory of the processor.
  • Calls the post_generate Tcl procedure (if defined in the Tcl file associated with an MDD or MLD file) for each of the drivers, OSs, and libraries visible to the processor.
  • Runs make (with targets include and libs) for the OSs, drivers, and libraries specific to the processor. On Unix platforms (Linux and Solaris), the gmake utility is used, while on NT platforms, make is used for compilation.
  • Calls the execs_generate Tcl procedure (if defined in the Tcl file associated with an MDD or MLD file) for each of the drivers, OSs, and libraries visible to the processor.
For more information about library generation read chapter 4 in the  Embedded System Tools Reference Manual.


Device driver architecture

The architecture of the device drivers is designed as a layered architecture as shown in the figure . The layered architecture accommodates the many use cases of device drivers while at the same time providing portability across operating systems, toolsets, and processors. The layered architecture provides seamless integration with an
RTOS (Layer 2), high-level device drivers that are full-featured and portable across operating systems and processors (Layer 1), and low-level drivers for simple use cases (Layer 0).

 Layer 2, RTOS adaptation
 Layer 1, High level drivers
 Layer 0, Low level drivers


xparameters.h


This source file centralizes basic configuration constants for all drivers within the system. Browsing this file gives the user an overall view of the system architecture. The device drivers and Board Support Package (BSP) utilize the information contained here to configure the system at runtime.
The amount of configuration information varies by device, but at a minimum the following items should be defined for each device:
  • Number of device instances
  • Device ID for each instance
  • A Device ID uniquely identifies each hardware device which maps to a device driver. A Device ID is used during initialization to perform the mapping of a device driver to a hardware device.
  • Device IDs are typically assigned either by the user or by a system generation tool. It is currently defined as a 16-bit unsigned integer.
  • Device base address for each instance
  • Device interrupt assignment for each instance if interrupts can be generated.
Here is an example:

/* Definitions for peripheral RS232_UART */

#define XPAR_RS232_UART_BASEADDR 0x40600000
#define XPAR_RS232_UART_HIGHADDR 0x4060FFFF
#define XPAR_RS232_UART_DEVICE_ID 1
#define XPAR_RS232_UART_BAUDRATE 9600
#define XPAR_RS232_UART_USE_PARITY 0
#define XPAR_RS232_UART_ODD_PARITY 0
#define XPAR_RS232_UART_DATA_BITS 8

The xparameters.h file can be found in the include directory.




Software driver source code

During the library generation (
libgen) run, the source code for every driver used, is copied to the SDK project directory libsrc, from the Xilinx source code repository. The old code will be overwritten and therefore we will never make any changes to the code in the libsrc directory. Here is the libgen log file.

Source code repository




Software device drivers used

To find out which software device drivers are used we can open Software Platform Settings and select Drivers. In the Xilinx Platform Studio SDK select Xilinx Tools->Software Platform Settings. The ETC peripheral has a generic driver assigned as default. We will add our own driver.




SDK project directory


The specified version of the driver source code is stored in the libsrc directory.





Let's take the GPIO driver as an example and look at different source files and their usage.

Header source file (xgpio.h and xgpio_l.h)

The
header files contain the interfaces for a component. There will always be external interfaces which is what an application that utilizes the component invokes.
  • The external interfaces for the high level drivers (Layer 1) are contained in a header file with the file name format x<component name>.h.
  • The external interfaces for the low level drivers (Layer 0) are contained in a header file with the file name format x<component name>_l.h.
The xgpio.h file contains the follwing type definitions.

/**************************** Type Definitions ******************************/


/**
 * This typedef contains configuration information for the device.
 */
typedef struct
{
    Xuint16  DeviceId;          /* Unique ID  of device */
    Xuint32  BaseAddress;       /* Device base address */
    Xboolean InterruptPresent;  /* Are interrupts supported in h/w */
    Xboolean IsDual;            /* Are 2 channels supported in h/w */
} XGpio_Config;

/**
 * The XGpio driver instance data. The user is required to allocate a
 * variable of this type for every GPIO device in the system. A pointer
 * to a variable of this type is then passed to the driver API functions.
 */
typedef struct
{
    Xuint32  BaseAddress;       /* Device base address */
    Xuint32  IsReady;           /* Device is initialized and ready */
    Xboolean InterruptPresent;  /* Are interrupts supported in h/w */
    Xboolean IsDual;            /* Are 2 channels supported in h/w */
} XGpio;

It also contains a number of
function prototypes. The functions themselves are defined in the different .c files found in the gpio source directory.

/************************** Function Prototypes *****************************/

/*
 * Initialization functions in xgpio_sinit.c
 */
XStatus XGpio_Initialize(XGpio *InstancePtr, Xuint16 DeviceId);
XGpio_Config *XGpio_LookupConfig(Xuint16 DeviceId);

/*
 * API Basic functions implemented in xgpio.c
 */
XStatus XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config *Config,
                            Xuint32 EffectiveAddr);
void    XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel,
                               Xuint32 DirectionMask);
Xuint32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel);
void    XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, Xuint32 Mask);


Configuration table xgpio_g.c

This file contains configuration tables for all devices that uses the GPIO device driver.

/*
* The configuration table for devices
*/

XGpio_Config XGpio_ConfigTable[] =
{
    {
        XPAR_LEDS_4BIT_DEVICE_ID,
        XPAR_LEDS_4BIT_BASEADDR,
        XPAR_LEDS_4BIT_INTERRUPT_PRESENT,
        XPAR_LEDS_4BIT_IS_DUAL
    },
    {
        XPAR_LEDS_POSITIONS_DEVICE_ID,
        XPAR_LEDS_POSITIONS_BASEADDR,
        XPAR_LEDS_POSITIONS_INTERRUPT_PRESENT,
        XPAR_LEDS_POSITIONS_IS_DUAL
    },
    {
        XPAR_PUSH_BUTTONS_POSITION_DEVICE_ID,
        XPAR_PUSH_BUTTONS_POSITION_BASEADDR,
        XPAR_PUSH_BUTTONS_POSITION_INTERRUPT_PRESENT,
        XPAR_PUSH_BUTTONS_POSITION_IS_DUAL
    },
    {
        XPAR_LCD_16X2_DEVICE_ID,
        XPAR_LCD_16X2_BASEADDR,
        XPAR_LCD_16X2_INTERRUPT_PRESENT,
        XPAR_LCD_16X2_IS_DUAL
    }
};

Adding the ETC software device driver


From the Xilinx documentation it isn't 100% clear how to add a new device driver. Here is how I did it and it seems to work.

1. Edit the ETC_system.mss file and add the etc driver. Like this:

   BEGIN DRIVER
     PARAMETER DRIVER_NAME = etc
     PARAMETER DRIVER_VER = 1.00.a
     PARAMETER HW_INSTANCE = ETC_0
  END

2. Add a new directory called drivers and the subdirectories as shown here:




3. Copy template files to src and data directories. We will use the gpio device driver source code as our template files. It is important to copy the .tcl and .mdd files to the data directory. Libgen will complain if it doesn't find these files.

4. Rename and edit the template files. For the moment we will not bother about writing working code. We will only rename everything called <gpio> to <etc>. Don't forget to make changes to the Makefile. Libgen will use the Makefile during library generation to compile and link the ETC device driver source code.

5. Edit the .mdd and .tcl files. Find out more
here.

6. Run library generation. Select Software->Generate Libraries and BSPs in the Xilinx Platform Studio. Libgen will search inside the drivers or pcores directories for device driver source code.

7. The ETC software device driver source code will be compiled into the library libxil.a together with all other device drivers.


Top  Next  Previous





Posted at 09:34 am by svenand
Comments (5)  

 
Jun 25, 2007
FPGA design from scratch. Part 37
Debugging our design

What to do if our design is not doing what we expected it to do. Then we need a
debugger.

Xilinx Microprocessor Debugger and GNU Software Debugging Tools

Using Xilinx Microprocessor Debugger (XMD) and GNU Debugger (GDB), we can debug our embedded application either on the host development system using an instruction set simulator or virtual platform, or on a board that has the FPGA loaded with our hardware bitstream. For more information on the GNU software debugging tools, refer to the Debug Overview. For more information on XMD, see the "Xilinx Microprocessor Debugger (XMD)" chapter in the Embedded System Tools Reference Manual.

Xilinx Microprocessor Debugger (XMD)

The Xilinx Microprocessor Debugger (XMD) is a tool that facilitates debugging programs and verifying systems using the PowerPC 405GP or MicroBlaze microprocessors. We can use it to debug programs running on a hardware board, Cycle-Accurate Instruction Set Simulator (ISS), or MicroBlaze Cycle-Accurate Virtual Platform (VP) system.

XMD provides a Tool Command Language (Tcl) interface. This interface can be used for command line control and debugging of the target as well as for running complex verification test scripts to test a complete system. XMD supports GNU Debugger (GDB) Remote TCP protocol to control debugging of a target. Some graphical debuggers use this interface for debugging, including PowerPC and MicroBlaze GDB (powerpc-eabi-gdb and mb-gdb) and the Platform Studio Software Development Kit (SDK), EDK's Eclipse-based Software IDE. In either case, the debugger connects to XMD running on the same computer or on a remote computer on the Network.

XMD reads Xilinx Microprocessor Project (XMP), Microprocessor Hardware Specification (MHS), and (Microprocessor Software Specification) (MSS) system files to better understand the hardware system on which the program is debugged. The information is used to perform memory range tests, determine MicroBlaze to Microprocessor Debug Module (MDM) connectivity for faster download speeds, and perform other system actions.

MicroBlaze Processor Target

XMD can connect through JTAG to one or more MicroBlaze processors using the opb_mdm Microprocessor Debug Module (MDM) peripheral. XMD can communicate with a ROM monitor such as XMDStub through JTAG or Serial interface. You can also debug programs using built-in Cycle-accurate MicroBlaze ISS.

MicroBlaze MDM hardware target


                                                                                                                  (Courtesy of Xilinx)

Debug session

This example demonstrates a simple debug session with a MicroBlaze MDM target. Basic XMD-based commands are used after connecting to the MDM target using the connect mb mdm.

==> xmd

XMD% connect mb mdm

connect mb mdm
Info:AutoDetecting cable. Please wait.
Info:Reusing 78010001 key.
Info:Reusing FC010001 key.
Info:Connecting to cable (Parallel Port - parport0).
Info: libusb-driver.so version: 2007-05-27 00:37:02.
Info: parport0: Info:baseAddress=0x0Info:, ecpAddress=0x400Info:
Info: LPT base address = 0000h.
Info: ECP base address = 0400h.
Can't open /dev/parport0: Permission denied
Info:LPT port is already in use. rc = FFFFFFFFh
Info:Cable connection failed.
Info:Reusing 79010001 key.
Info:Reusing FD010001 key.
Info:Connecting to cable (Parallel Port - parport1).
Info: libusb-driver.so version: 2007-05-27 00:37:02.
Info:Cable connection failed.
Info:Reusing 7A010001 key.
Info:Reusing FE010001 key.
Info:Connecting to cable (Parallel Port - parport2).
Info: libusb-driver.so version: 2007-05-27 00:37:02.
Info:Cable connection failed.
Info:Reusing 7B010001 key.
Info:Reusing FF010001 key.
Info:Connecting to cable (Parallel Port - parport3).
Info: libusb-driver.so version: 2007-05-27 00:37:02.
Info:Cable connection failed.
Info:Reusing A0010001 key.
Info:Reusing 24010001 key.
Info:Connecting to cable (Usb Port - USB21).
Info:Checking cable driver.
Info:File version of /home/svenand/cad/xilinx91i/bin/lin/xusbdfwu.hex = 1025(dec), 0x0401.
Info:File version of /usr/share/xusbdfwu.hex = 1025(dec), 0x0401.
Info: libusb-driver.so version: 2007-05-27 00:37:02.
Calling setinterface num=0, alternate=0.
DeviceAttach: received and accepted attach for:
  vendor id 0x3fd, product id 0x8, device handle 0x830b558
Info: Cable PID = 0008.
Info: Max current requested during enumeration is 280 mA.
Info: Cable Type = 3, Revision = 0.
Info: Cable Type = 0x0605.
Info: Setting cable speed to 6 MHz.
Info:Cable connection established.
Info:Firmware version = 1025.
Info:CPLD file version = 0012h.
Info:CPLD version = 0012h.

JTAG chain configuration
--------------------------------------------------
Device   ID Code        IR Length    Part Name
 1       0a001093           8        System_ACE
 2       05059093          16        XCF32P
 3       01e58093          10        XC4VFX12
 4       09608093           8        xc95144xl

MicroBlaze Processor Configuration :
-------------------------------------
Version............................6.00.b
No of PC Breakpoints...............2
No of Read Addr/Data Watchpoints...0
No of Write Addr/Data Watchpoints..0
Instruction Cache Support..........off
Data Cache Support.................off
Exceptions  Support................off
FPU  Support.......................off
Hard Divider Support...............off
Hard Multiplier Support............on - (Mul32)
Barrel Shifter Support.............off
MSR clr/set Instruction Support....on
Compare Instruction Support........on

Connected to MDM UART Target
Connected to "mb" target. id = 0
Starting GDB server for "mb" target (id = 0) at TCP port no 1234

Reading registers in MicroBlaze

XMD% rrd

rrd
    r0: 00000000      r8: 00000001     r16: 00000000     r24: 00000000 
    r1: 00001440      r9: 00000008     r17: 00000000     r25: 00000000 
    r2: 000010f8     r10: 00000000     r18: 00000000     r26: 00000000 
    r3: 00000001     r11: 00000000     r19: 00000000     r27: 00000000 
    r4: 00000000     r12: 00000000     r20: 00000000     r28: 00000000 
    r5: 00000000     r13: 00001158     r21: 00000000     r29: 00000000 
    r6: 0000000d     r14: 00000000     r22: 00000000     r30: 00000000 
    r7: 0000000a     r15: 0000005c     r23: 00000000     r31: 00000000 
    pc: 0000007c     msr: 00000000

Load program

Command: dow elf_file_name

XMD% dow SDK_projects/ETC_system_program/Debug/ETC_system_program.elf

dow SDK_projects/ETC_system_program/Debug/ETC_system_program.elf
    section, .vectors.reset: 0x00000000-0x00000003
    section, .vectors.sw_exception: 0x00000008-0x0000000b
    section, .vectors.interrupt: 0x00000010-0x00000013
    section, .vectors.hw_exception: 0x00000020-0x00000023
    section, .text: 0x00000050-0x00000f0b
    section, .init: 0x00000f0c-0x00000f2f
    section, .fini: 0x00000f30-0x00000f4b
    section, .ctors: 0x00000f4c-0x00000f53
    section, .dtors: 0x00000f54-0x00000f5b
    section, .rodata: 0x00000f5c-0x00000f9d
    section, .data: 0x00000fa0-0x00000ffb
    section, .jcr: 0x00000ffc-0x00000fff
    section, .bss: 0x00001000-0x0000143f
Downloaded Program SDK_projects/ETC_system_program/Debug/ETC_system_program.elf
Setting PC with Program Start Address 0x00000000

Set breakpoint

Command : bps <memory_loc>

XMD% bps 0x50
bps 0x50
Setting breakpoint at 0x00000050

Remove breakpoint

Command : bpr <memory_loc>

XMD% bpr 0x50
bpr 0x50

Display breakpoints

Command : bpl

XMD% bpl
bpl
0: HW BP: Address = 0x00000004
1: SW BP: Address = 0x00000050

Start program execution

Command : con [start_address] or con to continue from breakpoint

XMD% con 0
con
Info:Processor started. Type "stop" to stop processor

RUNNING> XMD% Info:Software Breakpoint 1 Hit, Processor Stopped at 0x00000050


Single step

Command : stp [number_of_instructions]

XMD% stp
stp
      54:   304010F8  addik    r2 , r0 , 4344

XMD% stp
stp
      58:   30201430  addik    r1 , r0 , 5168

XMD% stp
stp
      5C:   B9F40088  brlid    r15, 136

XMD% stp 10
stp 10
     10C:   20C01000  addi     r6 , r0 , 4096


Stop program execution

Command : stop

RUNNING> XMD% stop
stop
XMD% Info:User Interrupt, Processor Stopped at 0x00000068

Display program code

Command : dis <start address, number_of_instructions>

XMD% dis 0x50 20
dis 0x50 20
      50:   31A01158  addik    r13, r0 , 4440
      54:   304010F8  addik    r2 , r0 , 4344
      58:   30201430  addik    r1 , r0 , 5168
      5C:   B9F40088  brlid    r15, 136
      60:   80000000  Or       r0 , r0 , r0
      64:   20210010  addi     r1 , r1 , 16
      68:   B8000000  bri      0
      6C:   E0601000  lbui     r3 , r0 , 4096
      70:   3021FFE4  addik    r1 , r1 , -28
      74:   F9E10000  swi      r15, r1 , 0
      78:   BC030014  beqi     r3 , 20
      7C:   B8000028  bri      40
      80:   F8600FA8  swi      r3 , r0 , 4008
      84:   99FC2000  brald    r15, r4
      88:   80000000  Or       r0 , r0 , r0
      8C:   E8600FA8  lwi      r3 , r0 , 4008
      90:   E8830000  lwi      r4 , r3 , 0
      94:   BE24FFEC  bneid    r4 , -20
      98:   30630004  addik    r3 , r3 , 4
      9C:   30600001  addik    r3 , r0 , 1


Getting help

XMD% help
help

XMD Terminal Commands Types:
init......... Load/Initialize the System Files
connect...... Connect to System Target
files........ Load ELF/Data files
running...... Program Execution
breakpoints.. Setting Breakpoints/Watchpoints
trace........ Tracing and Profiling options
misc......... Miscellaneous Options
help......... Help on help

Type "help" to display XMD command types
Type "help" followed by above "type" for more options
XMD%

XMD% help running
help running

        Program Execution, Reading/Writing Registers and Memory
----- Syntax -----                 ----- Description -----
  run                                   Run program from <Start Address>
  con [address] [-quit]                 Continue
  stp [num_instrns]                     Step
  cstp [num_cycles]                     Cycle Step (Simulator/VP targets)
  rst [-processor]                      Reset the System/Processor
  stop                                  Stop
  rrd [reg num]                         Register Read
  srrd [reg name]                        Special Register Read
  rwr <register> <word>                 Register Write
  mrd <address> [num] [w|h|b]           Memory Read (default: 'w'ord)
  mrd_var <variable name> [ELF file]    Read memory at global variable
  mwr <address> <values> [<num> <w|h|b>]  Memory Write (default: 'w'ord)
XMD%

XMD% help breakpoints
help breakpoints

        Setting Breakpoints and Watchpoints
----- Syntax -----                 ----- Description -----
  bps <address|func name> [sw|hw]  Breakpoint Set. xmd uses last
                                     downloaded ELF file for function name
  watch <r|w> <addr> [data]        Set Read/Write Watchpoints.
  bpr <address|func name|bp id|all> Breakpoint/Watchpoint Remove. xmd uses last
                                    downloaded ELF file for function name
  bpl                              Breakpoints List
XMD%

XMD% help files

help files

        Specify/Download ELF or Data files to System Target
----- Syntax -----                 ----- Description -----
  dow <filename>                Download Elf File
  dow <filename> <addr>         Download PIC Elf File from <addr>
  dow <-data> <filename> <addr> Download Data/Binary File from <addr>
XMD%

XMD% help trace
help trace

        Trace/Statistics/Profile Commands
----- Syntax -----                 ----- Description -----
  tracestart [<filename>]               Start Tracing (For ISS/VP Targets)
  tracestop [done]                      Stop Tracing
  stats [filename]                      Generate Trace Stats (For Simulator Targets)
                                             <filename> Trace file for PPC Sim Only
  profile [-o <Gmon output File>]       Configure or Write Profile Output File
          [-config [sampling_freq_hz <value>]
          [binsize <value>] [profile_mem <Start Address>]
XMD%

XMD% help misc
help misc

        Misc Commands
----- Syntax -----                 ----- Description -----
  debugconfig [-step_mode <value>]      Configure the Debug Session
    [-memory_datawidth_matching <value>]
    [-reset_on_run <system | processor> <enable | disable>]
    [-vpoptions <bus_cycle_accuracy <enable | disable>>]
  state [target id]                     Display the Current State of all targets
                                       or <target id> target.
  dis <address> [num_words]             Disassemble (MicroBlaze Only)
  terminal [-jtag_uart_server [portno]]  Start JTAG-based Hyperterminal to
                                       communicate with MDM UART interface
  read_uart <start|stop> [TCL Channel ID] Read from MDM UART interface
  verbose [<level>]                      Toggle Verbose mode. Verbose Level = 1-3
XMD%



Using XMD in Xilinx Platform Studio

You can run the Xilinx Microprocessor Debugger (XMD) from a command line and use it exclusively for debugging. Alternately, XMD can serve as a link between the GNU debug option and your target board.

To open XMD from Xilinx Platform Studio (XPS), click Debug > Launch XMD.

The first time you open XMD, you are prompted to set the XMD options, and the XMD Debug Options dialog box opens automatically. Select the settings.

If you want to change the debug option setting later, you can do so by clicking Debug > XMD Target Options.

After you have set the debug options, the XMD terminal command-line window opens. On Startup, XMD does the following:

If an XMD Tcl script is specified, XMD executes the script and quits.

Otherwise, XMD is started in an interactive mode. In this case, XMD does the following:

  • Sources the ${HOME}/.xmdrc file. The configuration file can be used to form custom Tcl commands using XMD commands.
  • Opens the XMD Socket server, if the -ipcport option is given.
  • Loads system Xilinx® Microprocessor Project (XMP) file, if the -xmp option is given.
  • Uses Connect option file to connect to processor target, if the -opt option is given.
  • If –nx option is not specified, sources the xmd.ini file, if present in the directory.

The XMD% prompt is displayed. From the Tcl prompt, you can use XMD commands for debugging.

For a list of XMD commands, refer to the "Xilinx Microprocessor Debugger (XMD)" chapter of the Embedded System Tools Reference Manual.


Top  Next  Previous



Posted at 10:18 am by svenand
Comment (1)  

Next Page