Hardware:
This project required extensive use of Xilinx for hardware design. The entire hardware design can be categorized into the following control groups: keypad, LCD character display, motors, light sensors, solenoids, and bus control. Nearly all of the hardware was implemented in verilog code. Each is discussed in further detail below.
Bus Control:
The bus required a few control signals to be generated in hardware in order to function properly. First, the PD_OUT_EN needed to be set whenever data was driven on the bus to the processor, which occurs with a keypad or LCD data read. Next, a transaction acknowledge signal is required during a transaction to any of the memory-mapped space. Finally, the AD_OE signal was set to logical zero to avoid interference between the analog-to-digital logic and the bus data.
Keypad:
The keypad required constant polling, so we created a clock divider for the bus clock to create an appropriate polling frequency. The polling is done with a one-hot signal of the 4 columns and simultaneously reading the signals of the 4 rows, which complete the circuit when the corresponding button is pressed. The data that comes back from the keypad is then sampled and, if a key is pressed, raises a flag that causes an interrupt on the IRQ7 line and latches the data into a register. A final module for the keypad is a transaction decoder which is used to clear the interrupt when a read command occurs on the address specified by the memory-map.
Character Display:
The character display hardware consisted of transaction decoders and a data register. Transaction decoders were used to produce the correct LCD control signals during bus transactions with the correct memory-map address. These transactions could be either read or write, with a read signal used to check the LCD ready-bit and write transactions used with the data register to write the correct character or command to the LCD.
Motors and Light Sensors:
The motors made up another memory-map location to allow for a bus transaction to control signals that would be output to the expansion board. For each motor, we had a transaction decoder for a clockwise and counterclockwise movement and output signals that would control voltage to the motors with the help of an h-bridge. Another input to the decoders were the signals from the light sensors, which were put through debouncer and pulse-detect logic to remove glitching. The motor logic then counts the number of pulses and output the correct signal until the correct number of pulses – specified in the bus transaction – is reached. When this happens, another signal is output that triggers an interrupt on the IRQ1 line. Finally, there is another transaction decoder that outputs a signal to clear this interrupt. This is used so that the interrupt can be cleared from the ISR with a simple write command.
Solenoids:
The solenoids were interacted with via a final memory-map location. A transaction decoder generates a signal used to latch data from the processor into a register, which is driven to the expansion board.