You are on page 1of 44

Red Light, Green Light: all States are Finite

Traffic Light Controller -- FSMs and FPGAs --

Tiffany Wang 6.111 Introductory Digital Systems Laboratory October 12, 2005

Abstract The traffic light lamp is an American invention dating back to the advent of cars. From the earliest form of colored gas lamps to modern day cost-effective lamps using light emitting diodes (LEDs), traffic lights have played a crucial role in directing and keeping steady flow of traffic. Traffic signal phases are usually based on one of three systems: pre-timed, semi-actuated, and fully-actuated. The simplest control system utilizes a timer and preset parameters. More sophisticated systems may take into account the time of day, presence of traffic tracked with electronic sensors embedded in the pavement, or real time situations monitored with cameras and computers. Although it may seem like a simple device, the modern day traffic light can be very complicated in terms of control and timing. The Laboratory 2 Project takes an in depth look at the control system involved in traffic lights by using finite state machines (FSMs) and field-programmable gate arrays (FPGAs) to build a typical light. This report provides an overview of the composition of the controller and lays out the overall functionality of the controller in terms of state sequencing, timing, special functions such as walk request and car sensors, and user interface with the system. The report also steps through the design, implementation, testing, and debugging stages undergone while building the system, providing in depth explanations of how each submodule of the system was designed and how each submodule interacts through its inputs and outputs to contribute to the overall functionality of the system. By exploring the inner workings of a traffic light controller, the project touches on the process of system design, design implementation, and just one of countless applications of FSMs.

ii

Table of Contents Abstract.......................................................................................................................................... ii I. Overview................................................................................................................................... 1 II. Module Description/Implementation .................................................................................... 6 a. Synchronizer...................................................................................................................... 6 b. Walk Register .................................................................................................................... 7 c. Time Parameter ................................................................................................................ 9 d. Divider.............................................................................................................................. 10 e. Counter ............................................................................................................................ 11 f. Timer................................................................................................................................ 12 g. FSM .................................................................................................................................. 13 h. Labkit ............................................................................................................................... 16 III. Testing and Debugging ........................................................................................................ 17 IV. Conclusion ............................................................................................................................. 21 V. Appendix a. b. c. d. e. f. g. Synchronize.v ................................................................................................................. 22 Walk_reg.v ..................................................................................................................... 23 Time_param.v................................................................................................................. 24 Divider.v ......................................................................................................................... 26 Counter.v......................................................................................................................... 27 Timer.v............................................................................................................................. 28 Fsm.v ............................................................................................................................... 29

h. Labkit.v........................................................................................................................... 32 VI. List of References ................................................................................................................. 40

iii

Figures Figure 1: Diagram of street intersection..................................................................................... 1 Figure 2: Labkit LEDs.................................................................................................................. 3 Figure 3: Labkit buttons and switches........................................................................................ 3 Figure 4: Screenshot of Xilinx Project Navigator toolset.......................................................... 5 Figure 5: Xilinx Vertex-II Platform FPGA Labkit.................................................................... 5 Figure 6: Block diagram of traffic light controller .................................................................... 6 Figure 7: Schematic diagram of a synchronizer ........................................................................ 7 Figure 8: Synchronizer test bench............................................................................................... 7 Figure 9: Walk register test bench .............................................................................................. 8 Figure 10: Time parameter test bench, testing value output.. .................................................. 9 Figure 11: Time parameter test bench, testing reprogram and reset inputs. ....................... 10 Figure 12: Divider test bench..................................................................................................... 11 Figure 13: Counter test bench ................................................................................................... 12 Figure 14: Timer test bench. ...................................................................................................... 13 Figure 15: FSM state transition diagram ................................................................................. 13 Figure 16: FSM test bench ......................................................................................................... 16

Tables Table 1: Default interval timing parameters.............................................................................. 2 Table 2: State output values of FSM ......................................................................................... 15

iv

Overview Modern day traffic light signals are operated based on many different timing systems. The simplest control systems utilize preset time parameters while more complicated systems may alter timing parameters according to time of day, traffic flow, or real time situations such as accidents. Regardless of the timing scheme, all traffic light control systems must be able to transition between different light combinations according to a certain traffic sequence. This lab project involves designing and implementing a controller system used to operate a typical traffic light. The system must incorporate finite state machine (FSM) modules which map out state sequences corresponding to each of the traffic light combinations. The FSM also regulates the transitions between each of the states based on timing and user input signals. The traffic light designed in this lab is being implemented at an intersection between a Main Street and a smaller Side Street, as seen in Figure 1. Both streets have the conventional red, yellow, and green signal lights. In addition to the normal traffic lights, there are also walk buttons and car sensors at this intersection. The walk buttons are located at each corner of the intersection and allow pedestrians to trigger the walk light. The sensors are located on the Side Street and send signals to notify the controller whether there are still cars on the Side Street.

Figure 1: Diagram of street intersection [1]. Traffic lights along Main and Side streets, car sensors located along Side Street, Walk Buttons located at each corner of the intersection.

Each respective light is timed (in seconds) according to preset time parameters. As seen in Table 1, each time interval has an identifying parameter number and default value. The base interval (tBASE) is used for normal green lights, the extended interval (tEXT) is used for the walk light and sensor controlled green lights, and the yellow interval (tYEL) is used for the yellow lights. The interval lengths can be reprogrammed by the user to custom values.

Table 1: Default interval timing parameters [1]. Each of the three traffic light time intervals has an identifying parameter number and default value, both encoded in binary form.

The normal traffic light sequence involves a five state cycle. (1) (2) (3) (4) (5) green light on Main Street (thus red light on Side) for 2 lengths of tBASE seconds yellow light on Main Street (red light on Side) for 1 length of tYEL seconds green light on Side Street (red light on Main) for 1 length of tBASE seconds yellow light on Side Street (red light on Main) for 1 length of tYEL seconds cycle back to start of cycle, step (1)

However, there are a few conditions under which there is a deviation from the normal cycle. These include walk requests being asserted by the user and car sensors being triggered, signifying that there are still cars present along the side street. (1) walk request submitted by walk button: after the yellow light on Main Street, both traffic lights are set to red and the walk light is turned on for 1 length of tEXT , after which the walk request is cleared and the green light on the Side Street turns on, continuing the normal traffic cycle (2) sensor high at end of first tBASE interval of green light on Main Street: instead of the second tBASE interval, the green light on Main Street continues only for an additional tEXT seconds before the yellow light on Main Street turns on and the normal traffic cycle continues (3) sensor high at end of green light on Side Street: the green light on Side Street continues for an additional tEXT seconds before the yellow light on Side Street turns on and the normal traffic cycle continues

The traffic lights are displayed as a row of light emitting diodes (LEDs) on the Xilinx Labkit. As seen in Figure 2, each LED represents a different traffic light. LED[0] is the walk light, LED[1] through LED[3] represent the Side Street traffic light, and LED[4] through LED[6] represent the Main Street traffic light. The last light, LED[7], is used as a clock which flashes on or off at every second mark.

Figure 2: Labkit LEDs [2]. Along the bottom edge of the Xilinx Labkit, LED[0] represents the walk light, LED[1-3] represents the Side Street traffic light, LED[4-6] represents the Main Street traffic light, and LED[7] is used as a second counter.

The traffic light controller also takes in user inputs such as asserting walk requests, triggering the car sensor, reprogramming timing parameters, and resetting the traffic light system. The user interfaces with the controller through the use of buttons and switches located on the Xilinx Labkit, as diagrammed in Figure 3. Each switch and button corresponds to a different user input.

Figure 3: Labkit buttons and switches [2]. Users provide inputs to the traffic controller using the series of switches and buttons located along the lower edge of the Labkit. Inputs include walk requests, car sensors, new values for time parameters, and system resets.

The reset button (button0), is used to clear all inputs, reset all clocks and counters, set the time parameter values back to their default settings, and restart the traffic light sequence at the beginning of the normal cycle. 3

The sensor button (button1) is used to represent cars passing over the sensor on Side Street. A signal signifying the presence of cars is sent to the traffic controller when the button is held down by the user The walk request button (button2) is used to represent pedestrians pressing the walk buttons at the corners of the intersection. A walk request signal is sent to traffic controller when the button is pushed. Custom time intervals can be set using the labkit switches (switches0-5). This allows the user to set time intervals (tBASE , tEXT , tYEL) to different values in binary form, a switch in down position (towards number label on labkit) indicates a 0 while a switch in up position (away from number label) indicates a 1. Switch0 and switch1 (switch1 = MSB) indicates the time parameter number encoding of the interval being programmed (i.e. 10 = tYEL). Switch2 through switch5 (switch5 = MSB) indicate the time value being programmed. Since the value is a 4-bit number, the time intervals can only be set to a value between 0 and 15 seconds (i.e. 0111 = 7 seconds). The reprogram button (button3) sets the selected interval to the value as indicated by the switches and restarts the traffic light sequence from the beginning of the cycle.

The traffic light controller project was implemented in two stages: Verilog design and FPGA implementation. After reading over the specifications in the lab handout, the behavior of the system could now be determined. The overall system was broken down into smaller modules, each with a specific function. With this layout, visualizing how the system behaves as well as debugging the system during testing and implementation stages was a much easier and more efficient process. This first phase of the project involved mostly design and understanding the system from a functionality and performance standpoint. Each module of the traffic light controller was laid out in terms of inputs, outputs, role in the overall system, and interaction with other modules. The modules were then programmed in Verilog HDL (Hardware Description Language). The Xilinx Project Navigator toolset, as seen in Figure 4, was used to compile the Verilog code test and create waveform test benches to assess each modules outputs. After each module was successfully programmed and tested, they were integrated into the entire system under a top level Labkit.v module.

Figure 4: Screenshot of Xilinx Project Navigator toolset [3]. The Xilinx Integrated Software Environment (ISE) includes Project Navigator, which offers various integrated design tools for programmable logic. Verilog coded modules were compiled and then tested with simulations using the Xilinx toolset.

The second phase of the project involves the actual hardware implementation of the traffic controller. The successfully compiled and tested system written in software was converted into a *.bit file with the toolset and then downloaded on to the FPGA (Field-Programmable Gate Array) of the Xilinx Virtex-II Labkit, as seen in Figure 5, to verify with the kits LEDs, buttons, and switches that the controller was operating properly.

Figure 5: Xilinx Vertex-II Platform FPGA Labkit [2]. The Xilinx Vertex-II used to implement the traffic light controller is a 6-million gate platform-scale FPGA. The FPGA labkit is designed to support complex and high-performance projects and is equipped with built-in audio and video codecs, memory chips, and many other user interface features. 5

Module Description/Implementation The traffic light controller is broken into smaller modules, each with its own features that contribute to the overall system. See Figure 6 for the schematics of the system.

Figure 6: Block diagram of traffic light controller [1]. The traffic controller system consists of seven smaller modules, each with its own feature that plays a part in the overall functionality of the control system.

Synchronizer In this system, all user inputs (reset, sensor, walk, and reprogram buttons) can be changed at any point in time and are thus asynchronous with the system clock. Problems with metastability can arise if say an input value is changed very close to a rising clock edge. The ambiguity of whether the signal changed before or after the clock edge places the system at an unstable state. The input value falls into an invalid logic region and requires an arbitrary amount of time to settle into a valid logic state value, for example a logical 1 or 0. Meanwhile, this invalid input can produce metastability and invalid behavior in the rest of the system. To avoid this problem, the asynchronous inputs need to be synchronized to the internal clock before being used by the internal logic of the system. As seen in Figurer 7, a synchronizer is a series of registers (two in the case of this lab) which add delay between the asynchronous input and system logic, providing additional settling time for the input. 6

Figure 7: Schematic diagram of a synchronizer [4]. A synchronizer consists of a series of registers placed between the input and output of a system block. The synchronizer is used to match inputs (in) that are out of sync with the system clock (clk) to the rising edges of the clock.

The pulse synchronizer module ensures that all user inputs asserted through button presses are synchronized to the system clock. As seen in Figure 8, the module accepts the system clock and user interface signals as inputs and outputs a synchronized version of the input to other modules in the traffic light controller. The synchronizer essentially checks the value of the input at each rising clock edge and maps that value to a signal that is synchronous to the system clock. [See Appendix for Synchronizer module Verilog code]

Figure 8: Synchronizer test bench. The synchronizer takes in the system clock and signals from the user, asserted by button presses, as inputs and outputs a signal which reflects the value of the input signal, but not synchronized with the clock. Walk Register The walk register module handles the setting and clearing of the walk signal requested by pedestrians. Pedestrians can push the button at any point in time during the traffic light cycle, but the request will not be serviced until after the Main Street yellow light. The walk register module accepts the system clock, <reset_sync> and <wr_sync> from the synchronizer, and <wr_reset> from the FSM (finite state machine) as inputs and outputs <wr> back to the FSM. [See Appendix for Walk Register module Verilog code]

The outputted signal notifies the FSM module if there is a walk request and that a disruption in the normal traffic light cycle is needed for the walk light. As seen in Figure 9, the <wr> output is updated at every rising clock edge according to the modules input signals. If <reset_sync>, the synchronized version of the user asserted <reset> signal, is high, a pulse is sent to the walk register indicating that the <wr> value be cleared and set to its default low value. If <wr_reset> signal is high, a pulse is sent to the walk register also indicating that the <wr> value be cleared and set to its default low value. <wr_reset> is controlled by the FSM and is normally low until a high pulse is sent at the end of the walk light state to reset the walk signal. The walk request must be reset otherwise the system will enter the walk state during every subsequent cycle. If <wr_sync>, the synchronized version of the user asserted <walkrequest> signal, is high, a pulse is sent to the walk register indicating that a request for the walk light has been made and that the <wr> value be set to a high value. If none of the input signals are high, the value of <wr> is latched (held) for the clock cycle. Thus, after a walk request is asserted by the user and <wr> is set to high, this value is held until the allotted time in the traffic light cycle for the walk light and immediately cleared at the end of the walk interval by the FSM.

Figure 9: Walk register test bench. The walk register takes in the system clock and various inputs from the synchronizer and FSM. These inputs determine the state of the walk request and consequently the output of the module. High <wr_sync> produces a high <wr> output while a high <wr_reset> or <reset_sync> input produces a low <wr> output.

Time Parameter The time parameter module serves as the memory of the traffic light controller and stores the three time parameter values for the different time intervals (tBASE , tEXT , tYEL) on the FPGA. The module accepts the system clock, <reset_sync> from the synchronizer, 2-bit <selector> and 4-bit <valueIn> from the user, and 2-bit <interval> from the FSM as inputs and produces a 4-bit <value> output to the timer module. The timer module uses the value as a time limit for each traffic light state. [See Appendix for Time Parameter module Verilog code] The outputted <value> is a 4-bit binary encoding of the time interval length (i.e. 0110 = 6 seconds). As seen in Figure 10, the output value is controlled by the FSM via the <interval> input and is only updated whenever there is a change in the value of this input. This value of <interval> is the encoded parameter number of one of the three time intervals (i.e. 00 = tBASE) and is determined by the FSM based on the current state of the traffic light controller.

Figure 10: Time parameter test bench, testing value output. The time parameter module takes in the system clock and various inputs from the synchronizer, user, and FSM. The <interval> value from the FSM determines which time interval value to output (i.e. tBASE , tEXT , tYEL).

As seen in Figure 11, the modules output value can also be determined by the user by means of resetting the system or reprogramming the stored interval lengths. The time parameter module checks for a reset or reprogram assertion at every rising clock edge and updates the stored values accordingly. If <reset_sync>, the synchronized version of the user asserted <reset> signal, is high, a pulse is sent to the time parameter module indicating that the length of the time intervals should be reset to their defaulted values (6, 3, and 2 seconds respectively).

If <prog_sync> the synchronized version of the user asserted <reprogram> signal, is high, a pulse is sent to the time parameter module to reprogram the length on one of the stored intervals as indicated by the <selector> and <valueIn> inputs. The 2-bit <selector> input specifies which time interval to reprogram and the 4-bit <valueIn> input specifies the new reprogrammed value (i.e. <selector> = 00, <valueIn> = 1001; reprogram tBASE to 9 seconds). If neither <reset_sync> or <prog_sync> input signals are high, the values of tBASE , tEXT , or tYEL are latched (held) for the clock cycle.

Figure 11: Time parameter test bench, testing reprogram and reset inputs. The option of programming custom time interval values is handled by the time parameter module, which accepts the <selector>, <valueIn>, and <reprogram> values specified by the user. The new values set by the user are reflected in the modules output when the corresponding interval is selected with <interval>. The module also handles reset assertions which restore time intervals to preset values.

Divider In order to properly time the length of each traffic light time interval, a system of measuring time in seconds is required. The frequency of the system clock used in the traffic light controller is 27 MHz, but a 1 Hz signal is needed to generate a signal that is high for one clock cycle at every second. The divider module takes in the system clock in addition to the <reset_sync> from the synchronizer as inputs and outputs a <one_hz_enable> signal to the timer module. [See Appendix for Divider module Verilog code] Essentially the divider module is used to slow down the system clock by dividing its frequency by a certain factor (2.7x10^7 in the case of the traffic light controller), as seen in Figure 12. Based on the system clock input, the divider increments a counter at every rising clock edge. Once the counter reaches the division factor

10

(2.7x10^7), the output <one_hz_enable> is set to high for that clock cycle, thus producing a 1 Hz signal. The counter is then reset to zero as the cycle starts anew. If the <reset_sync> input is high (reset button pushed), the counter and output signal are both reset to zero. <one_hz_enable> is outputted to the timer module which uses the signal as a sort of local clock to keep track of how many seconds has passed in the current state.

Figure 12: Divider test bench. The divider module takes in the system clock and synchronized reset signal as inputs. The module is used to produce a lower frequency local clock by dividing the system clock by a certain factor (a factor of 5 is shown in the diagram).

Counter The counter module though not essential to the functionality of the traffic light controller system, is useful as a visual counter for testing the timing of the system. The module take in the system clock, <reset_sync> from the synchronizer, and <one_hz_enable> from the divider as inputs. [See Appendix for Counter module Verilog code] The <one_hz_enable> signal is used to determine the state of the modules <second> output. At every rising clock edge, the module also checks for the rising edge of the <one_hz_enable> signal. At every low to high transition, the <second> output is set to the inverse of its current value, otherwise its value is held (latched) for that clock cycle, as seen in Figure 13. If the <reset_sync> input is high (reset button pushed), the <second> output is reset to its default low value.
<second> is outputted to one of the LEDs on the Labkit, causing the LED to flash on or off

at every second mark.

11

Figure 13: Counter test bench. The counter module takes in the system clock, <reset_sync> signal from the synchronizer, and <one_hz_enable> from the divider as inputs. The counter provides a visual seconds counter by switching between high and low at every rising edge of <one_hz_enable>.

Timer The timer keeps track of how many seconds have passed during each of the traffic light time intervals and notifies the FSM once it has finished counting for a particular state. The timer module takes in numerous inputs: the system clock, <reset_sync> from the synchronizer, <one_hz_enable> from the divider, <value> from the time parameter module, and a <start_timer> signal from the FSM. [See Appendix for Timer module Verilog code] Like the counter module, the timer checks for the rising edge of the <one_hz_enable> signal at every rising clock edge and uses this input to determine the state of its output to the FSM, <expired>. The module functions normally by incrementing a counter at each rising edge of the <one_hz_enable> signal as long as <start_timer> is high. <start_timer> is provided by the FSM and is always high except at transitions between states. If <start_timer> is low, indicating a change of state, then the counter is reset to zero in order to begin timing the next state interval. The counter is also reset to zero if <reset_sync> is high. As can be seen in Figure 14, once the counter is equivalent to the 4-bit <value> encoded number specified by the time parameter module, <expired> is set to high for a single clock cycle. This output indicates to the FSM that the timer has finished counting for that state interval and acts as a trigger for state transitions.

12

Figure 14: Timer test bench. The timer acts as the local clock of the system, keeping track (in seconds) of the time interval length for each state. Taking in <one_hz_enable> from the divider and the time interval value from the time parameter module, the module increments an internal counter and notifies the FSM when to make state transitions.

FSM The FSM (Finite State Machine) module is the central unit of the traffic light controller. As seen in Figure 15, each of the states correspond to different traffic light combinations for the Main Street, Side Street, and walk lamp. In addition to controlling the sequencing of the traffic light and keeping track of what state of the cycle the light is currently in, the module delegates information to other modules in the system based on state of the system.

Figure 15: FSM state transition diagram. The different states of the FSM correspond to each of the traffic light combinations for both streets

13

and the walk lamp. No two traffic lights are green or yellow at the same time. The FSM module takes in numerous inputs: system clock, <reset_sync>, <sensor_sync>, and <prog_sync> from the synchronizer, <wr> from the walk request module, and <expired> from the timer module. [See Appendix for FSM module Verilog code] The state of the system (and thus the outputs of the FSM) is determined by its inputs. If <reset_sync> or <prog_sync>, the synchronized versions of the user asserted <reset> and <reprogram> signals, respectively, are high, then a high pulse is sent to the FSM module indicating that the state of the system should be reset to the starting state (State 0). If the <wr> signal is high, then a walk request has been asserted. The <wr> signal is determined by the walk register module and only affects the subsequent transition state of the system once the traffic light cycle enters State 2 (yellow light on Main Street), in which case the next state will be State 6 (walk light) instead of the normal State 3 (green light on Side Street). If <wr> is low, the traffic light sequence follows the normal cycle. If <sensor_sync>, the synchronized version of the user asserted <sensor> signal, is high at certain points in the traffic sequence, a break from the normal cycle occurs. When the sensor button is held down at the end of the starting state (State 0), the next state will be State 5 (short Main Street green light) instead of the normal State 1 (normal Main Street green light). Holding the sensor button will also affect transition states at the end of State 3 (Side Street green light), in which case the next state will be State 7 (extended Side Street green light) instead of the normal State 4 (Side Street yellow light). If <sensor_sync> is low, the traffic light controller follows the normal cycle. If the <expired> signal is high, then a state transition is needed. The <expired> signal is a pulse signal determined by the timer module and controls the timing of state transitions in the FSM. The signal is high only when the timer has finished counting for the current state interval and directs the FSM to transition to the next state in the traffic light cycle. Normally <expired> is low, in which case the current state is latched (held). The FSM module also produces numerous outputs: <wr_reset> to the walk request module, <start_timer> to the timer module, <interval> to the time parameter, and <LEDout> to control the LED lights on the Labkit. The outputs of the FSM are products of the current state of the traffic light controller: The <wr_reset> must be cleared once the traffic light sequence enters into the walk light state (State 6). By sending a high <wr_reset> signal to the walk register, the

14

register is reset and <wr> is set to low (no walk request). The walk request must be reset otherwise the system will enter the walk state during every subsequent cycle. The <start_timer> must be set high in order for the timer module to keep a running time counter for each state interval. The signal is low only at the point of state transitions, which triggers the timer to reset its counter to zero to start counting for the next state interval. As seen in Table 2, each state has a corresponding time interval and LED light combination, specified by the <interval> and <LEDout>, respectively. These outputs are only updated when there is a state change. The 2-bit <interval> output is the encoded parameter number of one of the three time intervals. This value is sent to the time parameter module to assert which interval value it outputs. The 7-bit <LEDout> output is the encoded order of LED lights to turn on or off on the Labkit. (i.e. 0011000 = green light on Main Street, red light on Side Street, and walk light off).

Table 2: State output values of FSM. Each state of the traffic light controller has a corresponding time interval length and LED light combination. These values are outputted by the FSM module to the time parameter module and labkit. State 0 1 2 3 4 5 6 7 Interval tBASE (00) tBASE (00) tYEL (10) tBASE (00) tYEL (10) tEXT (01) tEXT (01) tEXT (01) LEDout 0011000 0011000 0101000 1000010 1000100 0011000 1001001 1000010

The FSM is often referred to the brains of the system. As can be observed in Figure 16, it is the responsibility of FSM module to process almost all of the outputs of the other modules and in turn output correct values corresponding to system state to maintain the overall functionality of the traffic light controller.

15

Figure 16: FSM test bench. The FSM takes in numerous inputs from the other modules which determine the state of the traffic light control system. The module in turn must correct its outputs to reflect the state of the system, such as time parameters, counter triggers, and labkit LED displays. Labkit The labkit module is the top level module that connects all the individual submodules together to form the traffic light controller. The assignments of buttons, switches, and LEDs on the Labkit for the user I/O interface are also declared within this module. [See Appendix for Labkit module Verilog code] This is the module that is compiled, converted into a *.bit file, and downloaded onto the Xilinx Vertex-II Platform FPGA.

16

Testing and Debugging The longest, yet most important, process of this project was the testing and debugging stages. Though time consuming and a bit tedious, the best method found for testing the traffic light controller was to test and debug each individual part of the system separately before connecting them all together. Phase 1: Verilog Design In the first phase of the project, each part of the traffic light controller was designed and programmed in Verilog as separate modules. After completing the code for each part, the source code was synthesized (compiled) using the Xilinx toolset. Once the code compiled successfully, test benches were set up to test the functionality of each module. The Test Bench Waveform source allows the user to generate simulation results based on adjustments to the input values of the module. The test bench verification step could have been done more efficiently had test cases been laid out ahead of time. This would have ensured that most if not all cases were tested. Although the synchronizer module was already provided, a test bench waveform was generated to verify that pulse inputs that were not in sync with the system clock were mapped onto a synchronized output signal. To test the walk register module, the inputs (reset_sync, wr_sync, and wr_reset) were set to high and low values in various combinations to verify that the output signal (wr) reflected those values at the right time. The time parameter module was tested in a two stages: correct output and proper value reprogramming. For testing purposes, additional outputs (time_base, time_ext, and time_yel) were added to monitor values being stored by the time parameter. The first testing stage involved adjusting the 2-bit interval input and verifying that the corresponding 4-bit value output was correct. The second testing stage involved adjusting the 2-bit time parameter selector, 4-bit time value, and prog_sync inputs and verifying that the correct time interval was set to the user-specified value. The reset_sync was also tested to make sure stored values were reset to default values. Since the actual clock division factor used in the final implementation would be too large to visualize with the test bench, a smaller more manageable factor of 5 was used to test that the system clock was being divided properly by the divider module. An additional counter output was added to verify that the counter was being updated and that there were indeed five clock cycles in between each of the high enable pulses being outputted. The reset_sync was also tested to make sure all values were zeroed upon its assertion. This counter module had a simple test bench which involved setting the enable input on and off in a synchronous pattern (like a slowed version of the system clock) and verifying that the value (essentially state) of the output was changed and held based on the input. The reset_sync was also tested to make sure the output was zeroed upon its assertion.

17

The timer module was also tested in a couple of stages: proper increment of counter and proper assertion of the expired output. An additional output (counter) was added to monitor the value held by the timer counter. The first testing stage involved setting the enable input on and off in a synchronous pattern to verify that the counter was being incremented according to the enable signal (not the system clock) only when start_timer was high. It was also confirmed that the counter was reset to zero if start_timer was low at any point in time. The second stage involved setting the 4-bit value input to an arbitrary number and making sure that expire was outputted as a high pulse at the moment the counter matched the specified value. The reset_sync was also tested to make sure all values were zeroes upon its assertion. The FSM module was tested in an extensive series of stages: correct state transitions and proper interval and LED outputs. An additional output (state) was added to monitor the current state of the FSM. By asserting the expired input, the timing of state transitions could be tested. First the normal traffic light cycle was tested, then changes to deviation states were tested by turning the user inputs (i.e. walk request and sensor) on and off to verify that the FSM was transitioning to the correct states. The interval and LED outputs could be verified simultaneously as the FSM changed from state to state. Phase 2: FPGA implementation After all submodules were successfully compiled and test bench simulations verified, the submodules were all instantiated and properly wired to the other submodules and to the Labkit I/O ports in the top tier labkit.v module. The top tier module was then synthesized (compiled), implemented, and programmed as a *.bit file. The file was next downloaded and configured to the Xilinx FPGA Labkit device. Unfortunately the traffic light controller did not work as indicated by the test benches in the software simulations. The source of the problem was the manner in which output values were being assigned (i.e. blocking and non-blocking) which was creating problems with the timing of the traffic light controller. The next steps taken were to test each individual module on the Labkit. The overall testing and debugging process would have been more efficient if the testing had been done on the hardware to begin with, but the software simulation provided a clearer visualization and understanding of the modules functionality. The hardware testing would also have been less frustrating if it had been known from the start that the Labkit buttons and LEDs were inverted. The first step was to test the labkit inputs. Each of the buttons and switches were wired to the LEDs to verify that they were functioning correctly. The button inputs were also ran through the synchronizer to verify that the same output was observed. The divider was tested via the counter module. Since the high pulse of the one_hz_enable signal would be too fast to observe on the Labkit LED, the counter was used instead to turn the LED on or off each time the enable signal is high (effectively every second).

18

The timer module was tested based on proper timing of the expired signal. In addition to wiring in the already verified one_hz_enable signal from the divider, a forcedStart signal was wired from one of the switches to simulate the start_timer signal normally inputted from the FSM and four other switches were wired to the timer to simulate the time value normally passed in from the time parameter. The expired output signal was also wired to one of the Labkit LEDs. Under proper functionality, it was observed that the LED corresponding to the expired output signal would flash after the specified number of seconds would pass and only if the forceStart switch was high. If the switch were low and then high, the counter would restart its incrementing from zero. This was tested with different values by adjusting the switches. The time parameter module was tested based on proper values stored on the FPGA and outputted to the timer. First the output value of the module was tested by wiring the 4-bit output to four Labkit LEDs and observing how they changed based on the interval input. The interval input, which would normally be provided by the FSM, was wired to two switches. For example, if both switch0 and switch1 were low (00 = tBASE ), led3 and led0 would be off while led2 and led1 would be on (0110 = 6 seconds). This was also tested by wiring the output to the timer module and observing when the LED corresponding to the expired signal would flash. Once the correct output was verified, the reprogram functionality was tested in a similar manner. The user specified parameter and value were wired to the switches as in the normal schematic and the interval input fixed to a certain parameter to verify that the proper interval was being reprogrammed. The reset functionality was also tested by verifying the values were reset to their default settings upon assertion. The walk register was tested based on the status of the wr output. The output was wired to one of the Labkit LEDs to verify that it turned on and off based on which input (wr_sync, wr_reset, and reset) were asserted. If the walk request button was pushed, the LED would stay on until the reset button or button assigned to wr_reset was pushed. The most complex module, the FSM was again put through a series of tests to verify proper interval and LED outputs and correct state transitions. First, the interval output was wired to two Labkit LEDs and a switch controlled state value was added as an input to the module. Based on what state value was specified by the user, the LEDs would display which time parameter was being outputted to the time parameter module. For example, if switch2 was high and switch1 and switch0 were low (100 = State 4), led1 would be on and led0 would be off (10 = tYEL ). This was tested for every other state value. Second, the LEDout output was wired as specified in the schematic and tested in the same way as the interval input. Based on the state specified, it was verified that the proper combination of LEDs would be on or off corresponding to the traffic light.

19

Lastly, the state transitions of the FSM were tested by wiring in a forceExpired signal to one of the switches. Each time the expired switch was flipped on and off, the FSM would transition to the next state which was verified by observing the Labkit LEDs. After the normal traffic light cycle was confirmed, the state transitions were also tested with assertion of the walk request, sensor, reset, and reprogram inputs. After each module was tested, the traffic light controller ran successfully according to the lab specifications. There was one issue that arose when reprogramming any of the interval values to zero. Effectively the state should be bypassed if the corresponding interval had a zero value, but the observed behavior was that the FSM would either get stuck in the previous state or enter the state for a very brief moment. By changing the outputs of the FSM and time parameter modules to block assignments (determined by the change of another modules output as opposed to the clock edge) this ensured a simultaneous state transition and timing check and the FSM would correctly skip over the state with zero time length.

20

Conclusion One of the main objectives of the labs was to provide an introduction to the design methodology behind building digital systems. The first part of the implementation process was to lay out a design plan. A well designed system often must take timing, memory space, material cost, and other factors into account. In the case of the traffic light controller, the system was broken down into smaller modules, each with a clearly defined role in the system, rules of interaction with other modules, and inputs and outputs. By separating specific functions among different submodules, the system architecture was streamlined and the overall system more efficiently debugged, tested, and ran. The project lab also provided extensive practice with programming in Verilog HDL. After the design was laid out and approved, it was implemented in code for software-based design and simulation. Since no code template was given, the structure and functions of each module was entirely self-designed, implemented, debugged, and tested. Another concept that was stressed was the importance in differentiating between non-blocking and blocking assignments of variables and how each affects timing and efficient calculations in the overall system. The second part of the implementation process was building the design in hardware. The project provided a good introduction to using the Xilinx FPGAs in terms of porting the file to the Labkit, interfacing with the I/O ports, and debugging the design using hardware implementation. A traffic light controller is just one of countless systems applications that utilize finite state machines. By examining this single case study, the lab project presented and reaffirmed concepts learned in lecture, such as the use and functionality of latches, registers, and especially finite state machines. By breaking down the system into smaller modules, a deeper understanding of how the system works could be developed by considering how information is passed between each submodule and how each piece contributes to the larger system. Overall, the traffic light controller lab was a very good introduction and insight into important concepts and processes of digital systems design and implementation. However, something that could be further stressed in the lab is the correlation between the Verilog code and hardware. Unlike earlier circuits labs where physical wiring of the system was required, the use of Verilog presents a purely logic based view of the systems architecture. It is understandable that at this higher level of design, it is unnecessary to deal with the lower hardware architecture such as gates and latches, but it is a good thing to know or at least visualize what are the physical counterparts of all those if and case statements.

21

Synchronize.v
// pulse synchronizer // synchronize (asynchronous) user inputs to system clock module synchronize(clk,in,out); parameter NSYNC = 2; // number of sync flops. input clk; input in; output out; reg [NSYNC-2:0] sync; reg out; always @ (posedge clk) begin {out,sync} <= {sync[NSYNC-2:0],in}; end endmodule

must be >= 2

22

Walk_reg.v
// walk register // manages state of walk request signal module walk_reg(clk, reset, wr_input, wr_reset, wr); input clk, reset, wr_input, wr_reset; output wr; reg wr = 0; always @ (posedge clk) begin // if reset = 1 if(reset) wr <= 0; else begin if(wr_reset) wr <= 0; else if(wr_input) wr <= 1; else wr <= wr; end end endmodule

// end of walk cycle // walk button asserted

23

Time_param.v
// time parameter // stores, changes, and specifies time interval values module time_param(clk, reset, selector, valueIn, reprogram, interval, valueOut); // default timing parameters parameter t_BASE = 6; parameter t_EXT = 3; parameter t_YEL = 2; parameter BASE = 0; parameter EXTEND = 1; parameter YELLOW = 2; input input input input clk, reset, reprogram; [1:0] selector; [3:0] valueIn; [1:0] interval;

output [3:0] valueOut; reg [3:0] valueOut; // timing parameters reg [3:0] timeBase = t_BASE; reg [3:0] timeExt = t_EXT; reg [3:0] timeYel = t_YEL; always @ (posedge clk) begin // if reset = 1 if(reset) begin // set interval values to default: 6,3,2 timeBase <= t_BASE; timeExt <= t_EXT; timeYel <= t_YEL; end // else if reprogram = 1 else if(reprogram) begin // case: selector case(selector) // set timeBase BASE: timeBase <= valueIn;

24

// set timeExt EXTEND: timeExt <= valueIn; // set timeYel YELLOW: timeYel <= valueIn; // default hold values endcase end

end // change valueOut whenever interval changes always @ (interval) begin case(interval) // interval from FSM // output valueOut to timer // timeBase BASE: valueOut = timeBase; // timeExt EXTEND: valueOut = timeExt; // timeYel YELLOW: valueOut = timeYel; // default, hold value default: valueOut = valueOut; endcase end endmodule

25

Divider.v
// divider // 1 Hz cycle produced from 27MHz clock module divider(clk, reset, enable); input clk, reset; output enable; reg [24:0] counter = 0; // dividing clock by factor of 2.7x10^6 integer divideFactor = 27000000; always @ (posedge clk) begin if(reset) // if reset = 1, reset counter begin counter <= 0; end else // else, increment counter begin counter <= counter+1; end // reset counter if divideFactor reached if(divideFactor == (counter-1) ) counter <= 0; end // if counter = divideFactor, 1 Hz enable = 1 assign enable = (divideFactor == counter) ? 1 : 0; endmodule

26

Counter.v
// counter // debugging second counter, change light state at each enable module counter (clk, reset, enable, light); input clk, reset, enable; output light; reg light; always @ (posedge clk) begin // if reset = 1 if(reset) light <= 0; else begin if(enable) light <= ~light; else light <= light; end end endmodule

27

Timer.v
// timer // tracks time elapsed in each state, triggers state transitions module timer(clk, reset, enable, value, start, expired); input clk, reset, enable, start; input [3:0] value; output expired; reg [3:0] counter; always @ (posedge clk) begin // if reset = 1, reset values and output if(reset) begin counter <= 0; end else begin // if start = 1, trigger counter to start if(start) begin // increment counter only on high enable if(enable) counter <= counter+1; end // if start = 0, reset counter else counter <= 0; end end // when counter reaches time limit, trigger expired high assign expired = (value <= counter) ? 1 : 0; endmodule

28

Fsm.v
// fsm // controls sequencing of traffic light controller based on input module fsm(clk, reset, sensor, walk, reprogram, expired, walk_reset, start, interval, LED); // state parameters parameter STATE_START = parameter STATE_GMAIN_B parameter STATE_YMAIN = parameter STATE_GSIDE_B parameter STATE_YSIDE = parameter STATE_GMAIN_E parameter STATE_WALK = parameter STATE_GSIDE_E // interval parameters parameter BASE = 0; parameter EXT = 1; parameter YEL = 2; input clk, reset, sensor, walk, reprogram, expired; output walk_reset, start; output [1:0] interval; output [6:0] LED; reg [1:0] interval; reg [6:0] LED; reg [3:0] state = STATE_START; always @ (posedge clk) begin // if reset = 1 or reprogram = 1 if (reset || reprogram) begin // restart state <= STATE_START; end else begin // STATE TRANSITIONS: if expired = 1 if (expired) begin case(state) // end of normal cycle

0; = 1; 2; = 3; 4; = 5; 6; = 7;

// // // // // // // //

Gm(base), Rs, W_off ; Gm(base), Rs, W_off ; Ym(yel), Rs, W_off ; Rm, Gs(base), W_off ; Rm, Ys(yel), W_off ; Gm(ext), Rs, W_off ; Rm, Rs, W_on; Rm, Gs(ext), W_off;

t_BASE 00 t_BASE 00 t_YEL 10 t_BASE 00 t_YEL 10 t_EXT 01 t_EXT 01 t_EXT 01

29

STATE_YSIDE: state <= STATE_START; // sensor triggered STATE_START: begin if(sensor) state <= STATE_GMAIN_E; else state <= state+1; end STATE_GSIDE_B: begin if(sensor) state <= STATE_GSIDE_E; else state <= state+1; end // walk triggered STATE_YMAIN: begin if(walk) begin state <= STATE_WALK; end else state <= state+1; end // end of short Green main STATE_GMAIN_E: state <= STATE_YMAIN; // end of walk STATE_WALK: state <= STATE_GSIDE_B; // end of extended Green side STATE_GSIDE_E: state <= STATE_YSIDE; // else, increment state default: state <= state+1; endcase end end end // change interval and LED outputs whenever state changes always @ (state)

30

begin case(state) STATE_START: // Gm(base), Rs, W_off ; t_BASE 00 begin interval = BASE; LED = 7'b0011000; // 24 end STATE_GMAIN_B: // Gm(base), Rs, W_off ; t_BASE 00 begin interval = BASE; LED = 7'b0011000; // 24 end STATE_YMAIN: // Ym(yel), Rs, W_off ; t_YEL 10 begin interval = YEL; LED = 7'b0101000; // 40 end STATE_GSIDE_B: // Rm, Gs(base), W_off ; t_BASE 00 begin interval = BASE; LED = 7'b1000010; // 66 end STATE_YSIDE: // Rm, Ys(yel), W_off ; t_YEL 10 begin interval = YEL; LED = 7'b1000100; // 68 end STATE_GMAIN_E: // Gm(ext), Rs, W_off ; t_EXT 01 begin interval = EXT; LED = 7'b0011000; end STATE_WALK: // Rm, Rs, W_on; t_EXT 01 begin interval = EXT; LED = 7'b1001001; // 73 end STATE_GSIDE_E: // Rm, Gs(ext), W_off; t_EXT 01 begin interval = EXT; LED = 7'b1000010; // 66 end endcase end assign start = (expired) ? 0 : 1; assign walk_reset = (state == STATE_WALK) ? 1 : 0; endmodule

31

Labkit.v
////////////////////////////////////////////////////////////////////// ///////// // // 6.111 FPGA Labkit -- Template Toplevel Module // // For Labkit Revision 004 // // // Created: October 31, 2004, from revision 003 file // Author: Nathan Ickes // ////////////////////////////////////////////////////////////////////// ///////// // // CHANGES FOR BOARD REVISION 004 // // 1) Added signals for logic analyzer pods 2-4. // 2) Expanded "tv_in_ycrcb" to 20 bits. // 3) Renamed "tv_out_data" to "tv_out_i2c_data" and "tv_out_sclk" to // "tv_out_i2c_clock". // 4) Reversed disp_data_in and disp_data_out signals, so that "out" is an // output of the FPGA, and "in" is an input. // // CHANGES FOR BOARD REVISION 003 // // 1) Combined flash chip enables into a single signal, flash_ce_b. // // CHANGES FOR BOARD REVISION 002 // // 1) Added SRAM clock feedback path input and output // 2) Renamed "mousedata" to "mouse_data" // 3) Renamed some ZBT memory signals. Parity bits are now incorporated into // the data bus, and the byte write enables have been combined into the // 4-bit ram#_bwe_b bus. // 4) Removed the "systemace_clock" net, since the SystemACE clock is now // hardwired on the PCB to the oscillator. // ////////////////////////////////////////////////////////////////////// ///////// // // Complete change history (including bug fixes) // // 2005-Sep-09: Added missing default assignments to "ac97_sdata_out", // "disp_data_out", "analyzer[2-3]_clock" and

32

// "analyzer[2-3]_data". // // 2005-Jan-23: Reduced flash address bus to 24 bits, to match 128Mb devices // actually populated on the boards. (The boards support up to // 256Mb devices, with 25 address lines.) // // 2004-Oct-31: Adapted to new revision 004 board. // // 2004-May-01: Changed "disp_data_in" to be an output, and gave it a default // value. (Previous versions of this file declared this port to // be an input.) // // 2004-Apr-29: Reduced SRAM address busses to 19 bits, to match 18Mb devices // actually populated on the boards. (The boards support up to // 72Mb devices, with 21 address lines.) // // 2004-Apr-29: Change history started // ////////////////////////////////////////////////////////////////////// ///////// module labkit (beep, audio_reset_b, ac97_sdata_out, ac97_sdata_in, ac97_synch, ac97_bit_clock, vga_out_red, vga_out_green, vga_out_blue, vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync, vga_out_vsync, tv_out_ycrcb, tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data, tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b, tv_out_subcar_reset, tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff, tv_in_i2c_clock, tv_in_i2c_data, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso, tv_in_reset_b, tv_in_clock, ram0_data, ram0_address, ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b, ram0_bwe_b, ram1_data, ram1_address, ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b, ram1_bwe_b, clock_feedback_out, clock_feedback_in,

33

flash_data, flash_address, flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_sts, flash_byte_b, rs232_txd, rs232_rxd, rs232_rts, rs232_cts, mouse_clock, mouse_data, keyboard_clock, keyboard_data, clock_27mhz, clock1, clock2, disp_blank, disp_data_out, disp_clock, disp_rs, disp_ce_b, disp_reset_b, disp_data_in, button0, button1, button2, button3, button_enter, button_right, button_left, button_down, button_up, switch, led, user1, user2, user3, user4, daughtercard, systemace_data, systemace_address, systemace_ce_b, systemace_we_b, systemace_oe_b, systemace_irq, systemace_mpbrdy, analyzer1_data, analyzer2_data, analyzer3_data, analyzer4_data, analyzer1_clock, analyzer2_clock, analyzer3_clock, analyzer4_clock);

output beep, audio_reset_b, ac97_synch, ac97_sdata_out; input ac97_bit_clock, ac97_sdata_in; output [7:0] vga_out_red, vga_out_green, vga_out_blue; output vga_out_sync_b, vga_out_blank_b, vga_out_pixel_clock, vga_out_hsync, vga_out_vsync; output [9:0] tv_out_ycrcb; output tv_out_reset_b, tv_out_clock, tv_out_i2c_clock, tv_out_i2c_data, tv_out_pal_ntsc, tv_out_hsync_b, tv_out_vsync_b, tv_out_blank_b, tv_out_subcar_reset; input [19:0] tv_in_ycrcb; input tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2, tv_in_aef, tv_in_hff, tv_in_aff; output tv_in_i2c_clock, tv_in_fifo_read, tv_in_fifo_clock, tv_in_iso,

34

tv_in_reset_b, tv_in_clock; inout tv_in_i2c_data; inout [35:0] ram0_data; output [18:0] ram0_address; output ram0_adv_ld, ram0_clk, ram0_cen_b, ram0_ce_b, ram0_oe_b, ram0_we_b; output [3:0] ram0_bwe_b; inout [35:0] ram1_data; output [18:0] ram1_address; output ram1_adv_ld, ram1_clk, ram1_cen_b, ram1_ce_b, ram1_oe_b, ram1_we_b; output [3:0] ram1_bwe_b; input clock_feedback_in; output clock_feedback_out; inout [15:0] flash_data; output [23:0] flash_address; output flash_ce_b, flash_oe_b, flash_we_b, flash_reset_b, flash_byte_b; input flash_sts; output rs232_txd, rs232_rts; input rs232_rxd, rs232_cts; input input mouse_clock, mouse_data, keyboard_clock, keyboard_data; clock_27mhz, clock1, clock2;

output disp_blank, disp_clock, disp_rs, disp_ce_b, disp_reset_b; input disp_data_in; output disp_data_out; input button0, button1, button2, button3, button_enter, button_right, button_left, button_down, button_up; input [7:0] switch; output [7:0] led; inout [31:0] user1, user2, user3, user4; inout [43:0] daughtercard; inout output output input [15:0] systemace_data; [6:0] systemace_address; systemace_ce_b, systemace_we_b, systemace_oe_b; systemace_irq, systemace_mpbrdy;

output [15:0] analyzer1_data, analyzer2_data, analyzer3_data, analyzer4_data;

35

output analyzer1_clock, analyzer2_clock, analyzer3_clock, analyzer4_clock;

////////////////////////////////////////////////////////////////////// ////// // // I/O Assignments // ////////////////////////////////////////////////////////////////////// ////// // Audio Input and Output assign beep= 1'b0; assign audio_reset_b = 1'b0; assign ac97_synch = 1'b0; assign ac97_sdata_out = 1'b0; // ac97_sdata_in is an input // VGA assign assign assign assign assign assign assign assign Output vga_out_red = 10'h0; vga_out_green = 10'h0; vga_out_blue = 10'h0; vga_out_sync_b = 1'b1; vga_out_blank_b = 1'b1; vga_out_pixel_clock = 1'b0; vga_out_hsync = 1'b0; vga_out_vsync = 1'b0;

// Video Output assign tv_out_ycrcb = 10'h0; assign tv_out_reset_b = 1'b0; assign tv_out_clock = 1'b0; assign tv_out_i2c_clock = 1'b0; assign tv_out_i2c_data = 1'b0; assign tv_out_pal_ntsc = 1'b0; assign tv_out_hsync_b = 1'b1; assign tv_out_vsync_b = 1'b1; assign tv_out_blank_b = 1'b1; assign tv_out_subcar_reset = 1'b0; // Video Input assign tv_in_i2c_clock = 1'b0; assign tv_in_fifo_read = 1'b0; assign tv_in_fifo_clock = 1'b0; assign tv_in_iso = 1'b0; assign tv_in_reset_b = 1'b0; assign tv_in_clock = 1'b0; assign tv_in_i2c_data = 1'bZ; // tv_in_ycrcb, tv_in_data_valid, tv_in_line_clock1, tv_in_line_clock2,

36

// tv_in_aef, tv_in_hff, and tv_in_aff are inputs // SRAMs assign ram0_data = 36'hZ; assign ram0_address = 19'h0; assign ram0_adv_ld = 1'b0; assign ram0_clk = 1'b0; assign ram0_cen_b = 1'b1; assign ram0_ce_b = 1'b1; assign ram0_oe_b = 1'b1; assign ram0_we_b = 1'b1; assign ram0_bwe_b = 4'hF; assign ram1_data = 36'hZ; assign ram1_address = 19'h0; assign ram1_adv_ld = 1'b0; assign ram1_clk = 1'b0; assign ram1_cen_b = 1'b1; assign ram1_ce_b = 1'b1; assign ram1_oe_b = 1'b1; assign ram1_we_b = 1'b1; assign ram1_bwe_b = 4'hF; assign clock_feedback_out = 1'b0; // clock_feedback_in is an input // Flash ROM assign flash_data = 16'hZ; assign flash_address = 24'h0; assign flash_ce_b = 1'b1; assign flash_oe_b = 1'b1; assign flash_we_b = 1'b1; assign flash_reset_b = 1'b0; assign flash_byte_b = 1'b1; // flash_sts is an input // RS-232 Interface assign rs232_txd = 1'b1; assign rs232_rts = 1'b1; // rs232_rxd and rs232_cts are inputs // PS/2 Ports // mouse_clock, mouse_data, keyboard_clock, and keyboard_data are inputs // LED Displays assign disp_blank = 1'b1; assign disp_clock = 1'b0; assign disp_rs = 1'b0; assign disp_ce_b = 1'b1; assign disp_reset_b = 1'b0; assign disp_data_out = 1'b0; // disp_data_in is an input

37

// Buttons, Switches, and Individual LEDs // assign led = 8'hFF; // button0, button1, button2, button3, button_enter, button_right, // button_left, button_down, button_up, and switches are inputs // User I/Os assign user1 assign user2 assign user3 assign user4

= = = =

32'hZ; 32'hZ; 32'hZ; 32'hZ;

// Daughtercard Connectors assign daughtercard = 44'hZ; // SystemACE Microprocessor Port assign systemace_data = 16'hZ; assign systemace_address = 7'h0; assign systemace_ce_b = 1'b1; assign systemace_we_b = 1'b1; assign systemace_oe_b = 1'b1; // systemace_irq and systemace_mpbrdy are inputs // Logic Analyzer assign analyzer1_data = 16'h0; assign analyzer1_clock = 1'b1; assign analyzer2_data = 16'h0; assign analyzer2_clock = 1'b1; assign analyzer3_data = 16'h0; assign analyzer3_clock = 1'b1; assign analyzer4_data = 16'h0; assign analyzer4_clock = 1'b1; // connect submodules wire reset; wire sensor; wire walkrequest; wire reprogram; wire [1:0] selector; wire [3:0] valueIn; wire reset_sync; wire senor_sync; wire wr_sync; wire wr_reset; wire wr; wire prog_sync; wire one_hz_enable; wire start_timer; wire expired; wire [3:0] value; wire [1:0] interval; wire [6:0] LEDout; wire second;

38

// user inputs assign reset = ~button0; assign sensor = ~button1; assign walkrequest = ~button2; assign reprogram = ~button3; assign selector[1] = switch[1]; assign selector[0] = switch[0]; assign valueIn[3] = switch[5]; assign valueIn[2] = switch[4]; assign valueIn[1] = switch[3]; assign valueIn[0] = switch[2]; // LED assign assign assign assign assign assign assign assign output led[0] led[1] led[2] led[3] led[4] led[5] led[6] led[7]

= = = = = = = =

~LEDout[0]; ~LEDout[1]; ~LEDout[2]; ~LEDout[3]; ~LEDout[4]; ~LEDout[5]; ~LEDout[6]; second;

// // // // // // // //

walk Side Side Side Main Main Main Time

Green Yellow Red Green Yellow Red (seconds)

// synchronize inputs synchronize synchronize1 synchronize synchronize2 synchronize synchronize3 synchronize synchronize4 // instantiate submodules

(clock_27mhz, (clock_27mhz, (clock_27mhz, (clock_27mhz,

reset, reset_sync); sensor, sensor_sync); walkrequest, wr_sync); reprogram, prog_sync);

// timer timer timer1 (clock_27mhz, reset_sync, one_hz_enable, value, start_timer, expired); // divider divider divider1 (clock_27mhz, reset_sync, one_hz_enable); // time_param time_param time_param1 (clock_27mhz, reset_sync, selector, valueIn, reprogram, interval, value); // walk_reg walk_reg walk_reg1 (clock_27mhz, reset_sync, wr_sync, wr_reset, wr); // fsm fsm fsm1 (clock_27mhz, reset_sync, sensor_sync, wr, reprogram, expired, wr_reset, start_timer, interval, LEDout); // counter counter counter1 (clock_27mhz, reset_sync, one_hz_enable, second); endmodule

39

List of References [1] C. Terman, Laboratory 2 FSMs and FPGAs project handout for 6.111 Introductory Digital Systems Laboratory, MIT Fall 2005. [2] R. Ballantyne, Labkit Documentation [Online]. Available : http://web.mit.edu/6.111/www/f2005/index.html [3] Xilinx Design Tools: Project Navigator for Xilinx Product and Services Available: http://www.xilinx.com/products/design_resources/design_tool/index.htm [4] S. Ward, Synchronization, Metastability, and Arbitration lecture notes for 6.004 Computation Strucutres, MIT Fall 2005.

40