This chapter introduces you to the design and test of microcontroller + FPLD designs using the XS40 and XS95 Boardsä .
The material presented in this addendum assumes you are familiar with the following topics:
· designing logic using the XC4000 FPGA or XC9500 CPLD (The Practical XILINX Designer from Prentice-Hall is a good introduction to this topic);
· the architecture and electrical characteristics of the 8031 microcontroller (the 8031 is a ROM-less version of Intel’s 8051, so check www.intel.com for more information);
· writing and debugging programs for the 8031.
The basic design flow for building microcontroller+FPLD applications is shown in Figure 1.
Figure 1: Microcontroller + FPLD design flow.
Initially you have to get the specifications for the system you are trying to design. Then you have to determine what inputs are available to your system and what outputs it will generate.
At this point, you have to partition the functions of your system between the microcontroller and the FPLD. Some of the input signals will go to the microcontroller, some will go to the FPLD, and some will go to both. Likewise, some of the outputs will be computed by the microcontroller and some by the FPLD. There will also be some new intra-system inputs and outputs created by the need for the microcontroller and the FPLD to cooperate.
In general, the FPLD will be used mainly for low-level functions where signal transitions occur more frequently and the control logic is simpler. A specialized serial transmitter/receiver would be a good example. Conversely, the microcontroller will be used for higher-level functions where the responses occur less quickly and the control logic is more complex. Reacting to commands passed in by the receiver is a good example.
Once the design has been partitioned and you have assigned the various inputs, outputs, and functions to the microcontroller and the FPLD, then you can begin doing detailed design of the software and hardware. For the software, you can use your favorite editor to create a .
ASM assembly-language file and assemble it with asm51 to create a.HEX file for the 8031 microcontroller on the XS Board. For the FPLD hardware portion, you will enter truth-tables and logic equations into a .ABL file and compile it into a .BIT or .SVF bitstream file using the XILINX F1 programming software. With the 8031-program file and the FPLD bitstream file in hand, you can download them to the XS Board using the XSLOAD program. XSLOAD stores the contents of the .HEX file into the 32 KByte RAM on the XS Board and then it reconfigures the FPLD by loading it with the bitstream file.When the XS Board is loaded with the hardware and software, you need to test it to see if it really works. The answer usually starts as "No'' so you need a method of injecting test signals and observing the results. XSPORT is a simple program that lets you send test signals to the XS Board through the PC parallel port. You can trace the reaction of your system to signals from the parallel port by programming the microcontroller and the FPLD to output status information on the LED digit (much like placing "printf'' statements in your C language programs). This is admittedly crude but will serve if you don't have access to programmable stimulus generators and logic analyzers.
The 8031 microcontroller and the FPLD on the XS Board are already connected together. These existing connections save you the effort of having to wire them yourself, but they also impose limitations on how your program and the FPLD hardware will interact. A high-level view of how the microcontroller, RAM, and FPLD are connected is shown in Figure 2
Figure 2: Connections between the 8031 microcontroller, RAM, and FPLD of the XS Board.
The 12 MHz oscillator output goes directly to a synchronous clock input of the FPLD. The FPLD can control the clock it sends to the
XTAL1 input of the microcontroller.The 8031 multiplexes the lower eight bits of a memory address with eight bits of data and outputs this on its
P0 port. Both the RAM data lines and the FPLD are connected to P0. The RAM uses this connection to send and receive data to and from the 8031. The FPLD is programmed to latch the address from P0 under control of the ALE signal and send the latched address bits to the lower eight address lines of the RAM.Meanwhile, the upper eight bits of the address are output on port
P2 of the 8031. The RAM uses the lower seven of these address bits. The FPLD also receives the upper eight address bits and decodes these along with the PSEN and read/write control line (from pin P3.6 of port P3) from the 8031 to generate the CS and CE signals that enable the RAM and its output drivers, respectively. Either of the CS or OE signals can be pulled high to disable the RAM and prevent it from having any effect on the rest of the XS Board circuitry.One of the outputs of the FPLD controls the reset line of the microcontroller. The 8031 can be prevented from having any effect on the rest of the circuitry by forcing the
RST pin high through the FPLD. (When RST is active, most of the 8031 pins are weakly pulled high.)Many of the I/O pins of ports
P1 and P3 of the 8031 connect to the FPLD and can be used for general-purpose I/O between the microcontroller and the FPLD. In addition to being general-purpose I/O, the P3 pins also have special functions such as serial transmitters, receivers, interrupt inputs, timer inputs, and external RAM read/write control signals. If you aren't using a particular special function, then you can use the associated pin for general-purpose I/O between the microcontroller and the FPLD. In many cases, however, you will program the FPLD to make use of the special-purpose 8031 pins. (For example, the FPLD could generate 8031 interrupts.) If you want to use the special-purpose pin with an external circuit, then the FPLD I/O pin connected to it must be tristated.An LED digit connects directly to the FPLD. The FPLD can be programmed so the microcontroller can control the LEDs either through
P1 or P3 or by memory-mapping a register for the LED into the memory space of the 8031.The PC can transmit signals to the XS Board through the eight data output bits of the printer port. The FPLD has direct access to these signals. The microcontroller can also access them by programming the FPLD to pass the data output bits onto the FPLD I/O pins connected to the 8031. The printer port data bits are also passed through the cascade header to the next XS Board in the chain (if there is one).
Communication from the XS Board back to the PC also occurs through the parallel port. Four of the parallel port status pins are connected to three pins of
P1 and one pin of P3. Either the microcontroller or the FPLD can drive the status pins. The PC can read the status pins to fetch data from the XS Board.When two XS Boards are connected through the cascade port, they can communicate through five pins on ports
P1 and P3. This creates a five-bit communication channel between adjacent XS Boards. The arrangement of the bits is such that the UART receiver pin of the top XS Board is connected to the UART transmitter pin of the other XS Board. This makes it possible to do one-way serial communication between XS Boards using the built-in UARTS of each 8031.The
UINFC40.UCF file shown in Listing 1 details how the pins of the XC4000 FPGA connect to the other components on the XS40 Board. The UINFC95.UCF file shown in Listing 2 details how the pins of the XC9500 CPLD connect to the other components on the XS95 Board. (The line numbers in each listing are provided for explanatory purposes only. They are not part of the actual file contents.) Here is a line-by-line description of what is contained in these user-constraint files:Line 1: The 12 MHz clock from the external oscillator enters through this pin.
Lines 4-11: These pins are outputs which control the individual segments of the LED digit. Note that the decimal-point segment (
led<7>) is not connected on the XS40 Board.Lines14-21: The eight data bits from the PC parallel port enter the FPLD through these pins. For the XS40 Board, the upper-most two data bits (
PC_D<6> and PC_D<7>) cannot be specified in a user-constraints file because these are special-purpose pins. To access these data bits on the XS40 Board you will have to use the special-purpose schematic symbols MD0 and MD2.Line 24: The FPLD sends a clock signal to the 8031 clock input through this pin.
Line 25: The FPLD controls the active-high reset input of the 8031 through this pin.
Line 26: The FPLD monitors this pin for a falling edge which indicates it should latch the lower eight bits of an address from the multiplexed address/data bus of the 8031.
Line 27: The FPLD monitors this pin for a low level which indicates the 8031 is accessing the program memory.
Line 28: The FPLD monitors this pin for a low level which indicates the 8031 is reading a byte from the data bus.
Line 29: The FPLD monitors this pin for a low level which indicates the 8031 is writing a byte to the data bus.
Lines 30-37: The multiplexed address/data bus of the 8031 appears on these pins of the FPLD. The FPLD can latch the lower eight bits of the address on the falling edge of
ALE_. After that, a byte of data will appear on these pins.Lines 38-45: The FPLD can output the latched lower-byte of the address on these pins which are also connected to the address pins of the external 32 Kbyte RAM.
Lines 46-53: The FPLD monitors the upper-byte of the address output by the 8031 on these pins and can output chip-select signals based upon the address values it sees. The external RAM also receives seven bits of this address byte (since it’s a 32 Kbyte RAM, it only needs fifteen address bits).
Line 56: The FPLD enables the output drivers of the external memory by placing a low level on this pin.
Line 57: The FPLD enables the external memory by placing a low level on this pin.
Lines 60-65: The CPLD on the XS95 Board has six free pins that aren’t connected to anything else, so they are listed at the end of Listing 2. The pins of the XC4000 FPGA on the XS40 Board are all used so there are no entries for free pins in the
UINFC40.UCF file.001- NET CLK LOC=P13; # CLOCK FROM EXTERNAL OSCILLATOR
002- #
003- # LED DRIVER OUTPUTS
004- NET LED<0> LOC=P25;
005- NET LED<1> LOC=P26;
006- NET LED<2> LOC=P24;
007- NET LED<3> LOC=P20;
008- NET LED<4> LOC=P23;
009- NET LED<5> LOC=P18;
010- NET LED<6> LOC=P19;
011- //NET LED<7> LOC=P30; # THERE IS NO CONNECTION TO THE DECIMAL-POINT
012- #
013- # DATA BITS FROM THE PC PARALLEL PORT
014- NET PC_D<0> LOC=P44;
015- NET PC_D<1> LOC=P45;
016- NET PC_D<2> LOC=P46;
017- NET PC_D<3> LOC=P47;
018- NET PC_D<4> LOC=P48;
019- NET PC_D<5> LOC=P49;
020- //NET PC_D<6> LOC=P32; # MUST USE SPECIAL-PURPOSE PINS FOR
021- //NET PC_D<7> LOC=P34; # ACCESSING PC_D<6> AND PC_D<7>
022- #
023- # MICROCONTROLLER PINS
024- NET XTAL1 LOC=P37; # INPUT CLOCK
025- NET RST LOC=P36; # ACTIVE-HIGH RESET
026- NET ALE_ LOC=P29; # ACTIVE-LOW ADDRESS LATCH ENABLE
027- NET PSEN_ LOC=P14; # ACTIVE-LOW PROGRAM-STORE ENABLE
028- NET RD_ LOC=P27; # ACTIVE-LOW READ
029- NET WR_ LOC=P62; # ACTIVE-LOW WRITE (ALSO CONTROLS RAM)
030- NET AD<0> LOC=P41; # MULTIPLEXED ADDRESS/DATA BUS
031- NET AD<1> LOC=P40;
032- NET AD<2> LOC=P39;
033- NET AD<3> LOC=P38;
034- NET AD<4> LOC=P35;
035- NET AD<5> LOC=P81;
036- NET AD<6> LOC=P80;
037- NET AD<7> LOC=P10;
038- NET A<0> LOC=P3; # DEMUXED LOWER BYTE OF ADDRESS
039- NET A<1> LOC=P4;
040- NET A<2> LOC=P5;
041- NET A<3> LOC=P78;
042- NET A<4> LOC=P79;
043- NET A<5> LOC=P82;
044- NET A<6> LOC=P83;
045- NET A<7> LOC=P84;
046- NET A<8> LOC=P59; # UPPER BYTE OF ADDRESS
047- NET A<9> LOC=P57;
048- NET A<10> LOC=P51;
049- NET A<11> LOC=P56;
050- NET A<12> LOC=P50;
051- NET A<13> LOC=P58;
052- NET A<14> LOC=P60;
053- NET A<15> LOC=P28;
054- #
055- # RAM CONTROL PINS
056- NET OE_ LOC=P61; # ACTIVE-LOW OUTPUT ENABLE
057- NET CE_ LOC=P65; # ACTIVE-LOW CHIP ENABLE
Listing 1: User-constraint file for the XS40 Board (UINFC40.UCF).
001- NET CLK LOC=P9; # CLOCK FROM EXTERNAL OSCILLATOR
002- #
003- # LED DRIVER OUTPUTS
004- NET LED<0> LOC=P21;
005- NET LED<1> LOC=P23;
006- NET LED<2> LOC=P19;
007- NET LED<3> LOC=P17;
008- NET LED<4> LOC=P18;
009- NET LED<5> LOC=P14;
010- NET LED<6> LOC=P15;
011- NET LED<7> LOC=P24;
012- #
013- # DATA BITS FROM THE PC PARALLEL PORT
014- NET PC_D<0> LOC=P46;
015- NET PC_D<1> LOC=P47;
016- NET PC_D<2> LOC=P48;
017- NET PC_D<3> LOC=P50;
018- NET PC_D<4> LOC=P51;
019- NET PC_D<5> LOC=P52;
020- NET PC_D<6> LOC=P81;
021- NET PC_D<7> LOC=P80;
022- #
023- # MICROCONTROLLER PINS
024- NET XTAL1 LOC=P10; # INPUT CLOCK
025- NET RST LOC=P45; # ACTIVE-HIGH RESET
026- NET ALE_ LOC=P20; # ACTIVE-LOW ADDRESS LATCH ENABLE
027- NET PSEN_ LOC=P13; # ACTIVE-LOW PROGRAM-STORE ENABLE
028- NET RD_ LOC=P32; # ACTIVE-LOW READ
029- NET WR_ LOC=P63; # ACTIVE-LOW WRITE (ALSO CONTROLS RAM)
030- NET AD<0> LOC=P44; # MULTIPLEXED ADDRESS/DATA BUS
031- NET AD<1> LOC=P43;
032- NET AD<2> LOC=P41;
033- NET AD<3> LOC=P40;
034- NET AD<4> LOC=P39;
035- NET AD<5> LOC=P37;
036- NET AD<6> LOC=P36;
037- NET AD<7> LOC=P35;
038- NET A<0> LOC=P75; # DEMUXED LOWER BYTE OF ADDRESS
039- NET A<1> LOC=P79;
040- NET A<2> LOC=P82;
041- NET A<3> LOC=P84;
042- NET A<4> LOC=P1;
043- NET A<5> LOC=P3;
044- NET A<6> LOC=P83;
045- NET A<7> LOC=P2;
046- NET A<8> LOC=P58; # UPPER BYTE OF ADDRESS
047- NET A<9> LOC=P56;
048- NET A<10> LOC=P54;
049- NET A<11> LOC=P55;
050- NET A<12> LOC=P53;
051- NET A<13> LOC=P57;
052- NET A<14> LOC=P61;
053- NET A<15> LOC=P34;
054- #
055- # RAM CONTROL PINS
056- NET OE_ LOC=P62; # ACTIVE-LOW OUTPUT ENABLE
057- NET CE_ LOC=P65; # ACTIVE-LOW CHIP ENABLE
058- #
059- # THESE ARE FREE PINS THAT DON'T CONNECT TO ANYTHING ELSE
060- NET FREE<0> LOC=P4;
061- NET FREE<1> LOC=P12;
062- NET FREE<2> LOC=P25;
063- NET FREE<3> LOC=P74;
064- NET FREE<4> LOC=P76;
065- NET FREE<5> LOC=P77;
Listing 2: User-constraint file for the XS95 Board (UINFC95.UCF).
General-Purpose FPLD+Microcontroller Interface CircuitryBefore designing a circuit to perform a specific function, it makes sense to develop a generic framework which contains the circuitry that is needed in every design. This circuitry is shown in Figure 3.
At the top of Figure 3 is the circuitry for bringing the eight bits data from the PC parallel port into the FPLD. Data on the
PC_D[7:0] bus is passed through a standard byte-wide input buffer (IBUF8) and appears on the internal PC_D_IN[7:0] bus. The same type of circuit is used to pass the upper address byte from the 8031 (A[15:8]) onto the internal address bus (A_IN[15:8]). Single-bit input buffers are used to transfer the CLK, ALE_, PSEN_, RD_, and WR_ signals onto the internal CLK_IN, ALE_IN_, PSEN_IN_, RD_IN_, and WR_IN_ signals, respectively.The multiplexed address/data bus (
AD[7:0]) is bidirectional because the 8031 uses it to both read and write bytes of data. An IBUF8 buffer is used to read the values on this bus onto the internal address/data bus (AD_IN[7:0]) of the FPLD. The FPLD also has to be able to write to the AD[7:0] bus in order to send data back to the 8031 or the external memory. For this reason, a tristate buffer (OBUFE8) is attached to the AD[7:0] pins. The value on the internal data bus (D_OUT[7:0]) will be forced onto AD[7:0] when the buffer driver-control signal (D_DRV) is high.The FPLD is responsible for de-multiplexing the 8031’s address/data bus so that a stable address can be sent to standard addressable devices like the external RAM. The byte-wide output register (
OFD8) is used to latch the lower byte of the address from the AD_IN[7:0] bus on the falling edge of ALE_IN_. The latched address is output on the A[7:0] pins.The 8031 clock receives its clock through the
XTAL1 pin which, in turn, is driven with the clock the FPLD receives (CLK_IN). So the FPLD circuitry and 8031 are synchronized. The 8031’s reset is driven by the value output on the least-significant bit of the PC parallel port (PC_D_IN0). This lets us reset the 8031 using the XSPORT utility.The active-low chip-select of the external RAM (
CE_OUT_) is driven by the most-significant address bit (A15_IN). When A15=0, the RAM is selected which effectively maps it into the address range 0000H-7FFFH. The outputs of the RAM are enabled by a low level on OE_ whenever the 8031 fetches an instruction (PSEN_IN_=0) or performs a data-read operation (RD_IN_=0).Figure 3: General-purpose interface circuitry.
Displaying patterns on the LED digit is a simple design that will show you how to work with the XS Board. The specifications for the design are that it should sequentially light each LED segment for about a second, extinguish it, and proceed with the next segment. After the last segment is tested, the entire procedure is repeated in an endless loop.
The system needs a clock input to time the interval each segment is active. Eight outputs are needed to drive the eight LED segments.
Now we have to partition the functions for our test system between the FPLD and the microcontroller. Obviously, we can build the entire test system using only the FPLD. A 24-bit counter in the FPLD can be incremented by the 12 MHz oscillator. The counter will roll-over approximately once a second at which time a rotating eight-bit shift register (also in the FPLD) will shift its contents. If this shift register is initially loaded with
00000001 and the output of each register bit drives one of the LED digital segments, then all eight segments will be individually tested after eight shifts. The testing will keep going as long as the clock is active.Since we wanted to show how to design a system using both the FPLD and the microcontroller, let's partition it a bit differently. The FPLD will still be used to drive the LED digit segments, but the sequencing of the test will be moved to the microcontroller. The microcontroller will write a rotating bit pattern to the LED and time each step in the test sequence using a delay loop. The FPLD will be used to implement a writable register within the address space of the microcontroller.
The schematic for the writable LED register is shown in Figure 4. The
AD_IN bus carries the data value from the 8031 into the LED register (FD8CE). The register is enabled for writing if the upper four address bits are all high. So any access by the 8031 to the address range F000H-FFFFH will enable the register. The data is loaded into the LED register at the end of a write operation by the rising edge on the WR_IN_ signal. The output of the register goes through a byte-wide output buffer (OBUF8) that drives the pins attached to the LED display. Because the register is writable but not readable, the D_DRV signal is tied to ground to disable the output buffers that would send data from the FPLD to the 8031.Figure 4: Circuitry for the LED register.
Listing 3 shows the 8031 program that works in concert with the FPLD hardware.
001- $MOD51
002-
003- STACKTOP EQU 70H ; start of stack (grows up)
004- LEDREG EQU 0F000H ; LED register address
005-
006- DSEG
007- ORG 30H
008- CNTR: DS 1 ; counter for wait routine
009-
010- CSEG
011- ORG 0000H ; program starts at 0 after reset
012- START:
013- ; initialize stack pointer ...
014- MOV SP,#STACKTOP
015- ; and the initial bit pattern to display
016- MOV A,#1
017- LOOP:
018- ; show the bits on the LED digit
019- MOV DPTR,#LEDREG
020- MOVX @DPTR,A
021- ; wait long enough so we can see the bits ...
022- CALL WAIT
023- ; then rotate the bit pattern ...
024- RL A
025- ; and then do it all again
026- JMP LOOP
027-
028-
029- ; this subroutine waits about 1 second
030- WAIT:
031- PUSH ACC
032- PUSH B
033- MOV cntr,#8
034- WAIT1:
035- MOV B,#255
036- WAIT2:
037- MOV A,#255
038- DJNZ ACC,$
039- DJNZ B,WAIT2
040- DJNZ CNTR,WAIT1
041- POP B
042- POP ACC
043- RET
044-
045- END
046-
Listing 3: LED tester assembly code for the 8031 microcontroller (LEDDISP.ASM).
The microcontroller program works as follows:
Line 4: An address for the LED register implemented in the FPLD is defined for the 8031.
Line 8: A byte of the internal RAM in the 8031 is reserved to serve as a counter in the WAIT subroutine.
Line 11: The microcontroller program is set to start at address 0000H which is the address the 8031 jumps to immediately after a reset. All 8031 programs for the XS Boards must be stored in the 32 KByte RAM. The FPLD was programmed to map the RAM into the range 0000H—7FFFH so there would be some RAM to hold the instructions where the 8031 expects to find them.
Line 16: The accumulator is initialized with the bit pattern 00000001. The '1' bit in the pattern will be rotated through all eight positions and loaded into the LED register each time to test all the segments of the LED digit.
Lines 19--20: The address of the LED register is written into the pointer used for accessing external memory, and then the value in the accumulator is indirectly written to the register.
Line 22: A call is made to the WAIT subroutine which inserts a delay of approximately one second. This gives us time to observe the segments of the LED digit before they get loaded with the next pattern.
Line 24: The contents of the accumulator are rotated so that the next LED segment will be activated on the next loop through the program.
Line 26: This transfers the program back to the start of the loop so the next LED segment can be checked.
Lines 30--43: The WAIT subroutine counts through 8 ´ 255 ´ 255 = 520,200 loop iterations at approximately 2 ms per iteration. This inserts a delay of about a second. The subroutine pushes and pops the A and B registers so they retain the same values upon exit from the subroutine.
The assembly code in the LEDDISP.ASM file is assembled using the command:
C:> ASM51 LEDDISP.ASM
This command will create the file
LEDDISP.HEX. (Make sure you have a copy of the mod52 file in the directory where you are performing the assembly. mod52 contains definitions for many of the internal register addresses of the 8052/8031. You can find mod52 in the directory created when you installed the XS Board software utilities.)Now you can download the
LEDDISP.HEX and LEDREG.BIT or LEDREG.SVF files to the XS Board. The downloading cable must be attached between the PC printer port and the J1 header of the XS Board. The actual downloading process for the XS95 Board is accomplished with the command:C:> XSLOAD -P 1 LEDDISP.HEX LEDREG.SVF
And the downloading process for the XS40 Board is done with this command:
C:> XSLOAD -P 1 LEDDISP.HEX LEDREG.BIT
XSLOAD
loads the RAM with the program found in the LEDDISP.HEX file. Then it configures the FPLD with the circuit description stored in the .SVF or .BIT file. The command given above assumes the XS Board is hooked to LPT1 so it uses the option -P 1. If the XS Board is hooked to LPT2 or LPT3, then use -P 2 or -P 3, respectively. (If you don't use the -P option at all, XSLOAD will use LPT1 as the default printer port.)Once you have the XS Board completely loaded, you would naturally ask: "Now what?'' For this simple example all you have to ensure is that the microcontroller is reset correctly. Recall that parallel port pin
D0 is connected to the RST line of the 8031 through the FPLD. The 8031 can be reset and released to start executing its program with the following command sequence:C:> XSPORT 1
C:> XSPORT 0
After you execute these two commands, you should see the LED segments being sequentially activated at one second intervals.
The LED display example in the previous section was very simple. All that was needed was a memory-mapped, writable register in the FPLD. What if we needed to perform the opposite operation and pass data from the FPLD back into the microcontroller?
The example in this section will show the design of a simple, eight-bit random number generator. The bit pattern output from the random number generator will be displayed on the LED digit.
The inputs and outputs for this design are the same as for the LED display: a clock input and eight LED driver outputs.
The design will be partitioned as follows:
· The microcontroller will be responsible for initializing the random number generator and then reading random numbers from the LFSR and writing the eight-bit patterns to the LED register in an endless loop. The microcontroller will insert a one-second delay between each write to the LED register so we can have time to observe the random numbers.
The FPLD circuitry is shown in Figure 5.
Figure 5: Random number generator circuitry.
The random number generation circuitry is included below the LED register from the previous section. The main component of the random number generator is an eight-bit loadable shift-register (SR8CLE). Because it will change its value whenever it is written or read, the shift-register is clocked with the logical AND of the RD_IN_ or WR_IN_ strobes so that a clock pulse is generated when either strobe goes low. In order to clock all the flip-flops in the shift-register at the same time, a clock buffer (BUFG) is inserted between the AND gate and the clock input. This reduces clock skew between the flip-flops of the shift-register and allows reliable shifting of the bits
The shift-register can be loaded with a seed by having the 8031 write to an address in the range C000H-CFFFH. A write to this address range places a logic 1 on the load control input (L) of the shift-register, sends the seed value over the AD_IN bus, and generates a rising edge on the register’s clock input at the end of the write operation.
The random number in the shift-register is fetched by having the 8031 read an address in the range E000H-EFFFH. A read to this address range forces the D_DRV signal high, thus turning on the buffer drivers in the FPLD (see Figure 3) that will send the value on D_OUT to the 8031.
Reading the random number generator also causes it to generate a new random number. If the address that is read is in the range E000H-EFFFH, then the shift-enable input (CE) will be raised to a logic 1. The low pulse on RD_IN_ will clock the shift-register. This causes the contents of the shift register to be shifted left and the value on the serial-input (SLI) is placed in the least-significant bit of the register. The new LSB is formed from the exclusive-OR of bits 3, 4, 5, and 7 of the old value in the shift-register. This combination of bits insures that the shift-register will pass through 255 distinct states before repeating.
The 8031 program that works with the random number generator is shown in Error! Reference source not found.. It is very similar to the one in the previous section so we will only discuss the differences:
Line 5: The memory address from which new random numbers are read is defined for the rest of the program.
Line 6: The memory address for writing the seed value to the random number generator is defined here.
Lines 18-20: The accumulator is loaded with a seed value that is then loaded into the random number generator.
Lines 23-24: A random number from the LFSR is indirectly read into the accumulator.
Lines 26-27: The bit pattern read from the random number generator is written to the LED register so we can see it.
001- $MOD51
002-
003- STACKTOP EQU 70H ; start of stack (grows up)
004- LEDREG EQU 0F000H ; LED register address
005- RNDGEN EQU 0E000H ; address for reading random num. gen.
006- SEED EQU 0C000H ; address for writing random num. gen. seed
007-
008- DSEG
009- ORG 30H
010- CNTR: DS 1 ; counter for wait routine
011-
012- CSEG
013- ORG 0000H ; program starts at 0 after reset
014- START:
015- ; initialize stack pointer ...
016- MOV SP,#STACKTOP
017- ; and the random number seed
018- MOV A,#1
019- MOV DPTR,#SEED
020- MOVX @DPTR,A
021- LOOP:
022- ; read a new random number from the FPGA ...
023- MOV DPTR,#RNDGEN
024- MOVX A,@DPTR
025- ; and show the random bits on the LED digit
026- MOV DPTR,#LEDREG
027- MOVX @DPTR,A
028- ; wait long enough so we can see the bits ...
029- CALL WAIT
030- ; and then do it all again
031- CALL WAIT
032- JMP LOOP
033-
034-
035- ; this subroutine waits about 1 second
036- WAIT:
037- PUSH ACC
038- PUSH B
039- MOV cntr,#8
040- WAIT1:
041- MOV B,#255
042- WAIT2:
043- MOV A,#255
044- DJNZ ACC,$
045- DJNZ B,WAIT2
046- DJNZ CNTR,WAIT1
047- POP B
048- POP ACC
049- RET
050-
051- END
Listing 4: Random number generator test assembly code for the 8031 microcontroller (RNDDISP.ASM).
As was shown before, you can download the RNDDISP.HEX and the RANDGEN.SVF files to the XS95 Board with the command:
C:> XSLOAD -P 1 RNDDISP.HEX RANDGEN.SVF
or to the XS40 Board with this command:
C:> XSLOAD -P 1 RNDDISP.HEX RANDGEN.BIT
The 8031 is reset and released to start executing its program with these commands:
C:> XSPORT 1
After this, you should see the LED segments being activated in random patterns. You can record several patterns and check that they match what would be generated by the LFSR of Figure 5.
Interested: