CST 331 Lab 3 -- EBI Introduction
Lab
Replace the values of the following two config pragmas with the
indicated values so that the system clock will run at 96
MHz. Also leave the PBCLK8 divider at its default value of
2. This will mean that the EBI is clocked at 48MHz.
#pragma config FPLLMULT =
MUL_64 // System PLL Multiplier (PLL Multiply by
64) FVco = 6MHz * 64 = 384MHz (350 < FVco < 700)
#pragma config FPLLODIV = DIV_4 // System PLL Output Clock
Divider (4x Divider) 384MHz / 4 = 96 MHz
Use the following EBI setup code which was presented in class and
is based on Example 47-5 from the reference manual. Note that
SRAM_ADDR_CS0 has been changed to 0xE0000000 so that the cache
does not interfere with EBI accesses.
// Global Defines
#define SRAM_ADDR_CS0 0xE0000000
#define MyEBIuint (*(unsigned int*) 0xE0000000)
#define RAM_SIZE 2*1024*1024
#include <stdint.h>
int main(void){
unsigned int * myptr = (unsigned int
*)SRAM_ADDR_CS0;
unsigned int myread, mywrite = 0xA5A5BDBD;
// Enable address lines [0:19]
CFGEBIA =
0x800FFFFF;
CFGEBIC = _CFGEBIC_EBIWEEN_MASK |
_CFGEBIC_EBIOEEN_MASK |
_CFGEBIC_EBIBSEN1_MASK |
_CFGEBIC_EBIBSEN0_MASK |
_CFGEBIC_EBICSEN0_MASK |
_CFGEBIC_EBIDEN1_MASK |
_CFGEBIC_EBIDEN0_MASK;
//Set CS0 to base physical address
0z20000000
EBICS0 =
0x20000000;
EBIMSK0 = ((6 <<
_EBIMSK0_MEMSIZE_POSITION) &
_EBIMSK0_MEMSIZE_MASK) |
// 2^(6+15) = 2^21 = 2MB
((1 << _EBIMSK0_MEMTYPE_POSITION) &
_EBIMSK0_MEMTYPE_MASK) |
// 1 = SRAM
((0 << _EBIMSK0_REGSEL_POSITION) &
_EBIMSK0_REGSEL_MASK);
// Use Timing Reg set 0
EBISMT0 = ((10 <<
_EBISMT0_TRC_POSITION) &
_EBISMT0_TRC_MASK) |
(( 3 << _EBISMT0_TAS_POSITION) &
_EBISMT0_TAS_MASK) |
(( 1 << _EBISMT0_TWR_POSITION) &
_EBISMT0_TWR_MASK) |
((10 << _EBISMT0_TWP_POSITION) &
_EBISMT0_TWP_MASK);
// TBTA, TPRC, PAGEMODE, PAGESIZE and
// RDYMODE bits all 0
//Keep default data width to 16-bits
EBISMCON = 0x00000000;
while(1) {
// Your code entered here
asm volatile("nop");
// for a breakpoint
}
}
You will add code to do individual reads and writes targeting the
EBI memory as required in the steps below. Set up the logic
analyzer, in order to observe the EBI bus cycles that are
produced. You will need to observe at least CS0, EBIA1, EBIA0,
BS1, BS0, OE, and WE. Please make
sure that exactly these labels appear on the logic analyzer
screens!
Note: This lab can be done on a uP1 board with
the HMZ144 so long as there is no LCD
mounted on the uP1 board, and there is no
keypad connected (since these devices are connected to
pins that the EBI will use). Otherwise it will need to be done on
a uP2 board.
The uP1 board also uses EBIA23/RH15 and EBIRDY2/RH11 (an input for
the EBI) for board LEDs. Also, EBIRP/RH2 is connected to the
HMZ144 board LED, and EBICS1 is connected to the SD card unit on
the HMZ144, and EBIRDY1 (an input for the EBI) is connected to a
pin in the HMZ144 UEXT 10 pin connector. But these pins are
not needed in this lab. Be careful
not to enable them if you are using a uP1 board. In
general don't enable any pins that are not strictly necessary.
Also note that there actually isn't any memory added to the EBI
bus yet (on either a uP1 or uP2), so the data returned by a read
will just be whatever the data bus happens to float to. It can be
helpful for future labs to note what value(s) the bus usually
floats to. Note that it can take a long time for a driven
bus to return to its floating level, so reading from the bus
relatively soon after writing to it will likely return the same
value.
1) Add the following code to do a 32 bit write to and a 32-bit read
from the EBI memory, both operations at address 0xE0000000 (note the
#define for MyEBIuint in the code above).
MyEBIuint = 0xA5A5BDBD;
myread = MyEBIuint;
Remember that since the example initialization code sets up CS0 for
a 16-bit bus width, 32-bit operations will be implemented via two
16-bit cycles. Obtain and print out black on white background logic
analyzer screen shots for these (you may be able to get both the
read and a write in one screen shot). Try to get the position and
zoom set so that the read and/or write fill the screen shot.
i) In this step, what processor
address bits will be placed on EBIA1 and EBIA0? (Note that
it is not processor address bits A1 and A0. If you are
unsure what is going on, review the class lecture material or
homework assignment, or redo this exercise at address 0xE0000004,
or talk to the professor.)
ii) Indicate, by making notes on the printout(s), which operation
is the read, which is the write, and what processor address was
targeted in each case and whether the more or less significant
half of the 32-bit word is being read or written in each 16-bit
cycle. Do this by indicating the processor A1, A0 value associated
with the LSByte of each half word. That is, say "this
16-bit cycle reads the half word at processor A1, A0 = ...", etc.
Make sure to report the processor
address A1 and A0, not the EBIA1 and EBIA0
values.
2) Verify the timing values chosen in the sample code by doing the
following:
a) What values were chosen for
timing for each of tRC, tAS, tWP and tWR in the EBISMT0 setting?
Give your answer in terms of
PBCLK8 cycles,
not
the encoded values for each bit field.
b) How much time in ns was actually used for tRC, tAS, tWP and tWR
in your read and write cycles?
i) Mark the time spans covered by
tRC, tAS, tWP and tWR on your printouts. Note the scale used on
each logic analyzer printout.
ii) List the times that were obtained for each of these
parameters using the logic analyzer.
c) One question we had when we went through the EBI documentation
was whether SYSCLK or PBCLK8 would be used for EBI timing. With
the information you collected, determine for certain which clock
is being used. Justify your answer by showing your work.
3) Make sure that the 32 bit read cycle follows the 32 bit write
cycle as closely as is possible in C. Measure the time between the
end of the write cycle and the start of the read cycle using the
current timing settings. (Don't forget to account for tWR in this
case .) Obtain a screenshot of this time if you haven't done
so already. Then, change the timing setup in EBISMT0 so that tBTA
now has a value of 7 rather than the 0 it had originally.
Again, measure the time between the write and read cycles. Did
increasing tBTA increase the time between the two 32 bit
cycles? Don't forget to account for tWR! If it doesn't
increase the time between the two cycles, demonstrate this fact
to the professor. Obtain a screen shot showing the
increased time. How much time did setting tBTA to 7 add to the time
between the cycles? Does it appear that the two cycles in the
screenshot obtained before increasing tBTA were back to back? [You
might have to try replacing the C code doing the write and read with
the following inline assembly: asm("lui $at, 0xE000; sw
$at, 4($at); lw $0, 0($at)"); and redoing the
two screenshots (one with tBTA 0 and one with it at 7)]. Also,
check the two screen shots to see if setting tBTA to 7 changed the
timing between the two 16 bit write cycles making up the 32
bit write and between the two 16 bit read cycles making up the 32
bit read. Why shouldn't you expect to see tBTA make any changes to
the timing between the two 16-bit reads, or the two 16-bit
writes? Did it?
4) Change the bus width to 8-bit (the sample code was set
for a 16-bit width) and repeat part 1 above, including the analyzer
screen shot printouts. (If the
screenshots don't look different you probably haven't switched to
8-bit mode!)
Indicate on the printout(s) which operation is the read,
which is the write, and what address was targeted in each case and
which byte of the 32-bit word is being read or written in each 8-bit
cycle. Do this by indicating the processor A1, A0 value
associated with each byte. That is, say "this 8-bit cycle reads the
byte at (processor address bits) A1, A0 = ...", etc. How does
the EBI treat processor address bits A0 and A1 differently for the 8
bit bus width compared to the 16 bit bus width?
5) Set back to a 16-bit bus width. We can use the following
inline assembly to exercise the bus using lwr and swr instructions:
asm("lwr %0, 0xE0000001":"=r"(myread));
asm("swr %0,
0xE0000001"::"r"(mywrite));
Note that these are each pseudo/macro instructions which will be implemented as an
lui for the address followed by the lwr or swr respectively.
Thus the lwr and swr will not be executed back to back. Also
note that the lwr and swr will only need to read/write the 3 bytes
of memory starting at 0xE0000001 through 0xE0000003 (bytes B C and D
in the following table).
Predict what 16-bit bus cycles will be needed in order to
implement each of these operations. Give diagrams showing what
you will expect to see on the logic analyzer before you actually
observe them on the logic analyzer. (Include all the signals
connected to the logic analyzer in your diagrams). Then, run
the experiment and obtain printouts of logic analyzer
screenshots showing these operations. Indicate on the
printout(s) which operation is the read, which is the write, and
which byte or bytes of the 3 byte quantity is being read or written
in each 16-bit cycle. Do this by indicating the processor
A1, A0 value associated with each byte. What
inconsistency
or unexpected finding do you observe?
6) Change the bus width to 8-bit and setup to test and
observe pagemode accesses with a page size of 4.
Choose a tPRC setting smaller that tRC. Read a 32-bit
quantity and obtain a printout of a logic analyzer screen shot
showing the operation. Label the printout showing the tRC
times and the tPRC times. Also indicate on the printout what your
tPRC and tRC (in PBCLK8 cycles) settings were.
7) In some systems, for a pagemode access to be started requires
that the first access be at EBIA1, EBIA0 = 00 (A1, A0 in 8-bit
mode). Still in 8-bit mode, use a lwr instruction to determine
if a pagemode access will be started if the first access is at
processor address A1, A0 = 01, and if a pagemode
access will be started if the first access is at processor address
A1, A0 = 10.
Record your conclusions and appropriately labeled logic
analyzer screenshots showing your results in each of these two
cases. Report what lwr instruction was used
in each screenshot. Also, one of your observations
should confirm the inconsistency you found in part 5.
Describe this and say
what you think is happening.
For your report, turn in labeled printouts of screen shots and your
answers to any questions posed above as a pdf file in Canvas..