The easiest
Microblaze project is probably the one created for the Digilent
Spartan2E board. This project is actually one step up from there.
It is advised that you walk through the Digilent tutorial first to get
a feeling for XPS and how it flows. This is especially important even
if you don't have a Digilent board as it will show you a very detailed
example of the flow of the software. The additions to this project (from
the Digilent project) are an additional BRAM, an interupt, and a timer.
Shown below is a picture of this project. Due to the size of the pictures,
it is often easier to print these pages on landscape.


Here is a memory
table for this project.
The overall concept of this project is that it will create two different
sets of block RAM. The final product will be a Microblaze microprocessor
that will have an interrupt that will print out a "T" through the UART
to the HyperTerminal. This will be done through the ISR (interrupt service
routine). The interrupt will occur whenever the timer times out and
causes an interrupt. The project also has a main body of code that will
use the UART to print out "Go Lobos" to the HyperTerminal and use the
GPIO to blink several LEDs. So, when the program is running you will
see a continuous string of "Go Lobos" on the screen with occasional
"T" letters sprinkled in whenever the timer times out. On a side note,
the Lobos are UNM's mascot. I also included some header pins to demonstrate
the capability to loop the GPIO back to the processor. I had to do some
minor modifications to the AFX board to accommodate my project. Here
is a picture of what the board looked like after modifications.
The general
concept for the board changes was the addition of the RS232 driver,
9-pin connector, header pins, and a reset switch.

To begin, I launched XPS and selected the settings shown above. This
is based on the Virtex1000 devices I received from the XUP. For the
path of the project directory, this is open to your selection. The key
to remember is to not pick a directory along your path that has spaces
in the directory name (i.e. my documents). It should be pointed out
at this point that this project is intensive in its requirements for
computer resources. I found out that although my 450MHz laptop with
a little under 200M of RAM was sufficient to do the Digilent project,
it was entirely insufficient to do this project without hours of time
for processing. On my 1.7GHz, 528Meg home machine it took approximately
one hour to generate the netlist and the bitstream. Plan accordingly.
For reference purposes later, here is a zip
file that contains the entire completed project.
Once you click
on OK you have created the shell of your project. This means that you
have developed (although virtually empty) the three main files needed
for your project. These files are the mhs (hardware specification),
mss (software specification) and mvs (version and overall information).
Next it will be necessary to add all the peripherals. Go to Project
-> Add/Edit cores.(dialog) within XPS. The Microblaze system is bus
centric, which means to me that everything needs to connect to a bus.
It is also necessary to remember that everything that makes up a Microblaze
system is made up of sections called peripherals. So, the best plan
is that we will first decide and choose all the different parts we desire
to make up our project and then we will connect them to the various
busses.

Go into XPS -> Add/Edit Cores...(dialog). I haven't chosen any of
the above peripherals in any particular order. The ordering isn't critical.
I changed the instance name to make them more understandable to me.
This would also make it easier if you choose to use several instances
of the same peripheral (i.e. two sets of block RAM). Here is a short
discussion on the different peripherals and why I chose them. The opb_bram_cntlr
is the controller for my 8k of Block ram that I chose to connect to
the OPB. You can tell it is 8k by my choice of address ranges.
Next is the
"myuart." This is the UART that I will use to connect all of my output
to the HyperTerminal. Both the "Go Lobos" and "T" will come through
the same UART. Next are the two sets of BRAM (block RAM). I could have
chosen to only use one set of BRAM but felt for the purposes of a tutorial
that it would be better to show one connected off of the LMB and one
off of the OPB. Mygpio is how I perform my input and output off of the
OPB. This is how I send and receive data from my header pins and my
LEDs. Mblaze is the main microprocessor core. It is the heart of the
project. Mytimer is the timer I will use to signal my interrupt. It
will count down to zero and then signal an interrupt. It will do this
repetitively. Myjtaguart is the interface to the JTAG system for debugging.
I will use this for my XMD and software debugger later in the project.
Myintercntlr is the interrupt controller. It will perform a function
when an interrupt is generated by the timer. Dual_lmb_cntlr is the LMB
controller for one portion of the 8k BRAM. Each BRAM is dual port. This
controller is a dual LMB controller that would allow you to connect
to the BRAM in two separate places. Once you click "OK" you will find
that your system.mhs file has been updated to reflect the presence of
your new project. Next it will be necessary to choose our busses and
connect the peripherals to them.
Go back to Add/Edit
cores within XPS and choose the Bus Connections tab.
I added two
LMB busses and one OPB bus. On the OPB bus, I chose the "opb_v20_v1_10_b"
bus which I then renamed opb_bus. This one bus is where I will connect
all of my opb devices to. I will also add two "lmb_v10_v1-00_a" busses.
I will rename these as d_lmb and i_lmb (for data and instruction bus).
For the procedures for adding and renaming busses, refer to the Digilent
tutorial. As shown above, I have made the bulk of my peripherials slaves
to the opb_bus. I have only chosen to make four master bus connections.
These four were determined by the available Microblaze options. Make
your bus connections the same as those shown above. I have also chosen
to rename the lower right hand corner port and connector names to make
them easier for me to recall what they are used for. Once this is done
click OK. Next we will need to assign ports to our design. Go back to
Project -> Add/Edit Cores . (dialog) and click on the Ports tab.
Shown above
is the final port allocation for the project. Once again, I have changed
a lot of the names of the nets to make them easier for me to remember
their purposes. The key to ports is to think of the processor as a whole
and not as individual pieces. For this processor project I know that
I am going to have certain things that are external to the design that
will end up being inputs and outputs to the FPGA. They are: the transmit
and receive for my UART, my system clock, my reset, and my general purpose
input and output. From the above diagram you can see where I have set
all these to Kind -> External. All of the rest of them I have made
Internal. This means they are signals used within the processor. Input
and output is fairly self-explanatory. For the range on the general
purpose I/O, I chose 0 to 6. This means I can deploy up to seven LEDs,
switches, or other I/O devices. In the case of this project I chose
to use two LEDs and a loop back header.
The next step is to modify any parameters from their defaults. Go back
to XPS and launch Add/Edit Cores.(dialog) once more. Choose the Parameters
tab. The bulk of the items will remain with their default settings.
We will not discuss any of the parameters that are not changing, only
the ones to modify. On the upper right hand side drop down menu, choose
"myuart".
There are
three items we are going to modify here. First, we will change the clock
rate to match our onboard 50MHz oscillator. We will change the baud
rate to 19.2k and the parity to zero.
The next parameter to modify is "mygpio." We are choosing not to use
the entire 32 bit width available. We are only going to need seven items.
All the rest of the parameters are left as default.
One of the most important
things in the software package is buried here on this page. In the upper
right corner of the page is a button called "Open PDF Doc." This is
where you will find the document manuals for each of the cores in the
project. This is kind of an unusual place to find them but their presence
is critical in understanding how each of them work. They are a key in
troubleshooting problems with projects, as I will show you at the end
of the tutorial.
We have now done a lot of
what needs to be done to create the hardware section of the microprocessor.
The next major portion is adding in the source code. Here
is a link to a file called "system.c." It is fairly well commented
out to allow you to understand better what we want it to do. Go ahead
and copy it into a directory within your project directory called "code."
Within XPS, click once to highlight the mblaze instance on the left
hand side of the screen. Then click on Project -> add program sources.
This allows you to specify different source code for different instances
of Microblaze processors if more than one was used. Browse over to the
system.c file and add it to the project. We are now getting close to
being able to finish developing our processor. Go back to XPS. Now we
must make some minor changes to the S/W settings of our timer and interface
controller to allow them to know where to find the interrupt handler
function and how to deal with it.
Right click on "mytimer"
and select S/W settings.
There are two things you
have to change here. The first is that you have to tell the timer
what the interrupt handler function is. As you can see, I have typed
in "timer_int_handler" into the space. This is the exact function
developed in the system.c file. The other change you have to make
is to set the Interface level to 0. This is because of the fact that
there are two timers in the timer core and we want to use the first
one. When you are done, click OK. Now right click on the interface
controller and select it's S/W settings.
The only thing
that needs to be changed here is the Interface Level. Change it to 0
to match the timer setting. Click OK and you are ready to create your
Microblaze processor. Add the .ucf file to the /data directory. Within
XPS choose Tools -> generate netlist. This shouldn't take very long.
When it has completed, choose Tools -> generate bitstream. This will
take awhile based on the power of your computer. Once it is finished,
go to Tools -> update bitstream. At this point some people like to
know exactly how big their code is to ensure that their BRAM is sufficient
for changes. To check this go to tools -> get program size.

What this tells
me is that I have 1302 bytes dedicated to instructions. This will be
my Go Lobos and my constants. I have 28 bytes for my globals. I have
1024 bytes dedicated for my block segments and my unitialized spaces.
These three sum up to the 2354 bytes for the entire program.
Once this is
done, use the iMPACT as shown in the Digilent project to download the
download.bit file to the board. Also as shown in the Digilent project,
launch the HyperTerminal. Your final project should look like the one
shown below.


Now I am going
to show you some troubleshooting tips to aid in researching out problems
should they arise. My problem that I had was that I wasn't sure my timer
was actually setting off an interrupt when it hit zero. To troubleshoot
this I want to use Software Debugger. Go back into XPS. Right click
on the mblaze core and choose S/W settings.

Change your
Mode from Executable to XmdStub and make sure your Debug Peripheral
is set to myjataguart. Next, click on the optimization tab.

Choose to
"create symbols for debugging." Click OK. The benefit here is that you
don't have to go through the entire process of regenerating the netlist
and bitstream all over again. All you have to do is go to tools ->
update bitstream. Once this has completed, use iMPACT to drop the new
download.bit file to the device. The initial difference you will notice
now is that the lights are no longer blinking and the Hyper Terminal
has no activity.
Connect using
the Tools ->XMD command and then typing "mbconnect stub". Once this
is done launch the Software Debugger from the Tools drop down menu.

Use the target selections shown above. Once this is done, Choose OK
and then File. From the File drop down menu choose the executable.elf
file from mblaze\code directory. You should be looking at a screen like
the one shown below.

In the upper tool bar is a screen button that says Memory. Go ahead
and launch it.

What I do is to sit one screen on top of the other. Since I am most
interested in the memory and what is happening at the timer location
(memory location ffff4300), I type that memory address into the address
field.

Now I click on the "Next" button within the software debugger and watch
the changes in the memory values.

