A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf ·...

41
A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06 Abstract In this paper we present a design for a traffic controller for an intersec- tion consisting of a main street, a side street, pedestrian crosswalks across either street, and a traffic sensor measuring the current quantity of side street traffic. The controller runs the standard green-yellow-red cycle for each street’s traffic. It also turns all traffic lights red and turns on a walk light for pedestrians wishing to cross either street when needed. Three time parameters determine the lengths of each of the signal stage time pe- riods, and these parameters are changeable without hardware alterations. 1

Transcript of A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf ·...

Page 1: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

A Traffic Controller for a Two-Street Intersection

Jeff Walden– 6.111

8.10.06

Abstract

In this paper we present a design for a traffic controller for an intersec-tion consisting of a main street, a side street, pedestrian crosswalks acrosseither street, and a traffic sensor measuring the current quantity of sidestreet traffic. The controller runs the standard green-yellow-red cycle foreach street’s traffic. It also turns all traffic lights red and turns on a walklight for pedestrians wishing to cross either street when needed. Threetime parameters determine the lengths of each of the signal stage time pe-riods, and these parameters are changeable without hardware alterations.

1

Page 2: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

Contents

1 Overview 41.1 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Implementation Overview . . . . . . . . . . . . . . . . . . . . . . 51.3 Using the Traffic Controller within the Labkit . . . . . . . . . . . 5

2 Description 72.1 Internal Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.1 Debouncer . . . . . . . . . . . . . . . . . . . . . . . . . . 82.2.2 Synchronizer . . . . . . . . . . . . . . . . . . . . . . . . . 82.2.3 Walk Register . . . . . . . . . . . . . . . . . . . . . . . . . 92.2.4 Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2.5 Time Parameters . . . . . . . . . . . . . . . . . . . . . . . 112.2.6 State Machine . . . . . . . . . . . . . . . . . . . . . . . . 112.2.7 Traffic Light . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.3 The Traffic Controller State Machine . . . . . . . . . . . . . . . . 12

3 Testing and Debugging 14

4 Conclusions 15

5 Appendix 175.1 labkit.v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175.2 Debouncer.v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.3 Synchronizer.v . . . . . . . . . . . . . . . . . . . . . . . . . . . 235.4 TimeParameters.v . . . . . . . . . . . . . . . . . . . . . . . . . . 235.5 Timer.v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.6 TrafficController.v . . . . . . . . . . . . . . . . . . . . . . . . 275.7 TrafficLight.v . . . . . . . . . . . . . . . . . . . . . . . . . . . 295.8 TrafficState.v . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.9 WalkRegister.v . . . . . . . . . . . . . . . . . . . . . . . . . . . 345.10 TestAll.v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345.11 TestTimeParameters.v . . . . . . . . . . . . . . . . . . . . . . . 355.12 TestTimer.v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375.13 TestTrafficController.v . . . . . . . . . . . . . . . . . . . . . 395.14 TestWalkRegister.v . . . . . . . . . . . . . . . . . . . . . . . . 40

List of Figures

1 The traffic controller’s typical intersection . . . . . . . . . . . . . 42 Traffic controller internal layout . . . . . . . . . . . . . . . . . . . 73 Simulation of the synchronizer using custom waveforms . . . . . 94 Simulation of the walk register using Section 5.14 . . . . . . . . 105 Controller states, transitions, durations, and outputs . . . . . . . 12

2

Page 3: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

6 Simulation of the state machine . . . . . . . . . . . . . . . . . . . 13

3

Page 4: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

1 Overview

1.1 Purpose

The traffic controller described here is intended for use at an intersection of amain street and a side street. The main street typically carries more traffic thanthe side street, but at peak periods the side street has enough traffic that thetraffic lights must adjust their timing. Each street’s traffic must obey a standardred-yellow-green traffic light. Traffic must also watch out for pedestrians, whomay cross the intersection when the walk light is illuminated. For simplicity,the intersection uses the Barnes Dance1 pedestrian crossing system, in which alltraffic stops and pedestrians cross the intersection in every direction. A typicalintersection for which the controller would be useful is illustrated in Figure 1.

Figure 1: The typical street intersection for which our traffic controller wouldbe useful

The traffic controller is adjustable to meet differing traffic demands. Alltime periods associated with the intersection may be controlled through threeseparate intervals: tBASE , tEXT , and tY EL. These three parameters determinethe duration of green, yellow, and red lights for traffic on both streets and theduration of the walk light for pedestrians, and all may be set and reset withouthardware modifications. Exact details of how these values affect durations arein Table 1.

1For further details, see the Barnes Dance article on Wikipedia.

4

Page 5: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

Duration Description in terms of time parametersMain green, side red tBASE plus either tEXT (if at the end of

tBASE the side street traffic sensor is high)or tBASE (otherwise)

Main yellow, side red tY EL

Main red, side green tBASE , and if at the end of that time theside street traffic sensor is high add anadditional tEXT

Main red, side yellow tY EL

Main red, side red, walklight on

tEXT

Table 1: Traffic signal durations in terms of the three time parameters tBASE ,tEXT , and tY EL

1.2 Implementation Overview

The implementation of the traffic controller is broadly broken down into fourcomponents: a programmable n-second timer, a read-write memory device fortime parameters, signal cleaning mechanisms to convert asynchronous or noisysignals into clean signals synchronized with the circuit clock, and a state ma-chine which uses the other components to produce the appropriate outputs andtransition from state to state.

With these boundaries established, the next step consisted of determiningthe inter-component interfaces: the number of inputs, outputs, and their widths.Next came the creation of Verilog implementations of each component, an over-all container, and test components to check for correct implementation; becausethe inputs and outputs of all components had already been determined, eachcomponent’s implementation occurred independently of the other components.Finally, integration testing ensured that all components worked together cor-rectly and that the final device correctly implemented the desired functionality.

1.3 Using the Traffic Controller within the Labkit

The traffic controller described is instantiated through the TrafficControllermodule implemented in Section 5.6. The traffic controller is used within thelabkit in Section 5.1; the controller’s inputs and outputs are connected to thevarious switches, buttons, and LEDs within the labkit as described in Table 2.

5

Page 6: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

Labkit I/O element Description of functionalityButton 0 Resets all time parameters to their original

values and restarts the traffic controllerEnter button The walk button for the traffic intersectionButton 3 Reprograms the selected time parameter with

the given value and restarts the traffic con-troller

Switch 7 Determines whether the traffic sensor readshigh (switch is in the “up” position) or low(switch is in the “down” position)

Switches 6-5 Determine the time parameter which wouldbe reprogrammed if the “reprogram” buttonwere hit (button 3); tY EL corresponds to 6high and 5 low, tEXT corresponds to 6 lowand 5 high, and tBASE corresponds to 6 and 5low (do not use high/high, which in a real-lifeuser interface to the controller would not evenbe a settable choice)

Switches 3-0 Determine the value to which the selectedtime parameter would be reprogrammed if the“reprogram” button were hit (button 3); theyencode a 4-bit binary number whose most sig-nificant bit is determined by switch 3 andwhose least significant bit is determined byswitch 0

LEDs 7-5 The main street’s traffic light; the LEDs cor-respond to the red, yellow, and green lightsrespectively

LEDs 4-2 The side street’s traffic light; the LEDs cor-respond to the red, yellow, and green lightsrespectively

LED 0 The pedestrian walk light

Table 2: The user interface to the traffic controller as presented by the 6.111labkit

6

Page 7: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

2 Description

2.1 Internal Overview

The traffic controller is divided into submodules to facilitate easier reuse of sub-functionalities, to separate state logic from parts with essentially mechanicalpurposes, and to simplify testing and implementation. The primary componentscomprising the traffic controller are a set of Debouncers, a Synchronizer, a WalkRegister, an n-second programmable Timer, a small memory for the values ofthe Time Parameters, and a State Machine controlling the sequence of opera-tions and outputs for the traffic controller as it proceeds through its internalstates. (The controller also includes two minor Traffic Light components whichconvert a number into the appropriate signal, although this behavior could beeasily moved within the state machine if desired.) The internal layout of thesecomponents is Figure 2; for the implementation of this layout, see Section 5.6.

Figure 2: Traffic controller internal layout

7

Page 8: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

2.2 Components

For further details on any component, see the appropriate section in the ap-pendix. Each component’s implementation is prefaced with an extensive de-scription of its interface, and this description is intended to provide sufficientinformation to use the module within another circuit.

2.2.1 Debouncer

A debouncer converts an input signal which can fluctuate rapidly between highand low into an output signal which is low unless the input signal has beencontinuously high for a period of time. The signal generated by a button pushis an example of such a signal; the mechanical element in the button whichcompletes the circuit will have a tendency to “bounce” upon the fixed-positionterminal in the circuit, resulting in a bouncy signal.

Internally, the debouncer keeps a count of how many clock cycles its inputsignal has been continuously high. If the input signal is not high or the countof the number of clock cycles it has been high is below a certain threshold, thedebouncer’s output is a low signal; otherwise, it is high. This is determined atthe rising edge of the clock every time it cycles.

As a side benefit, the debouncer also synchronizes its input signal with thecircuit’s clock, because it requires its signal remain consistently high for multipleclock cycles before it produces a steady high on its output. (See the Synchronizerfor more details on why this is necessary.)

Internally, the traffic controller uses debouncers to process and debouncebutton pushes, providing the controller internals with a clean, debounced signalfrom which each button’s pushed or unpushed state may be read.

The debouncer’s implementation is given in Section 5.2.

2.2.2 Synchronizer

A synchronizer ensures that an input signal does not enter a metastable state ifit changes too near the rising edge of the circuit’s clock. If this were to happen,the input signal might have an invalid value when read by the relevant circuitcomponent, resulting in randomly unpredictable behavior a small percentage ofthe time during use of the circuit. The traffic controller uses a synchronizer toprocess the input of the traffic sensor switch.

Internally, the synchronizer is simply a series of registers through which theinput signal passes, eventually reaching the synchronizer output after the delayof those registers. Each register forces its input closer and closer toward a validsignal, and by using a sufficient number of registers the probability of the outputbeing metastable is made as low as is desired.

As a switch, the traffic sensor is also initially glitchy after transitions for thesame mechanical reasons as buttons. However, because the sensor value is onlyread for one cycle at the end of internal states in the state machine, its stabilityis not nearly as important as ensuring the signal is valid. Consequently, weprefer a simpler synchronizer over a more complex debouncer.

8

Page 9: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

The synchronizer’s implementation is given in Section 5.3.

Figure 3: Simulation of the synchronizer using custom waveforms

2.2.3 Walk Register

The walk register stores whether or not the walk button has been pushed sincethe last pedestrian walk cycle occurred. It is set when the walk button is pushed,and it is reset by the traffic controller’s state machine at the end of the walkcycle which serves the walk request.

The walk register’s implementation is given in Section 5.9.

2.2.4 Timer

The timer measures any period of time from 0 to 15 seconds, in one-second in-tervals. The time measured is determined by a selector input, which determinesthe time parameter whose value is used as the duration of timer. The storedtime parameters have initial default values as given in Table 3.

The timer is started when the input signal startTimer is asserted high;this loads the timer with the value of the selected parameter (the timer takes

9

Page 10: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

Figure 4: Simulation of the walk register using Section 5.14

as inputs the time parameter values from the time parameter memory), resetsthe internal 1Hz clock to 0, and begins a one-second countdown until the de-sired time has passed. When the 1Hz signal is enabled, the time remaining iscompared with 1 (not 0 – consider that if the requested time measurement is 1second, we reach this comparison exactly one second later) and if it is 1, expiredis asserted high. We then decrement the time remaining by 1 and reset the 1Hzsignal to 0, even if the timer is expiring. By doing so, we ensure the timer doesnot fire until we wrap around to 1, which is sufficiently far in the future thatit should not interfere with components which require a few cycles to respondto timer expiration. Additionally, the timer module’s documentation explicitlystates that behavior after expired is asserted high for one cycle when the timerexpires is undefined, forcing the burden of dealing with wraparound upon thetimer’s user. (If desired, the timer could be turned off by the user by settinga time parameter to a non-zero value and continuously asserting startTimerhigh.)

Parameter Default value (seconds)tBASE 6tEXT 3tY EL 2

Table 3: Time parameter default values

10

Page 11: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

Special care must be taken to deal with the timing of a 0-second period.Because the timer compares against 1, a naive implementation would result in a16-second time instead of a 0-second time in this case. This issue is addressed bycomparing the selected time value against 0 when startTimer is asserted highand asserting expired high if the time value is equal to 0. This case inheritsthe usual behavior of startTimer, so subsequently the timer would become a16-second timer if the timer is not restarted (this wrapping behavior is stillexplicitly undefined). (Note that given the constraints on reasonable trafficcontroller functionality discussed in Section 2.2.5, however, 0-second timing cannever actually occur; it was in the process of testing 0-second timing that theenumerated practical constraints were discovered.)

The timer’s implementation is given in Section 5.5.

2.2.5 Time Parameters

The time parameters device is essentially a small memory for the three timeparameters mentioned earlier. It may be externally reprogrammed as desired,but it itself has no knowledge of the state of the traffic controller state machine,and in fact it does not even know of the existence of the state machine. Thedevice operates on the rising edge of the circuit clock, storing the input valuein memory and setting outputs as and when necessary based on the inputs atthat moment.

The implementation of this device required that two issues be addressed:determining which parameter values were allowed to be 0 and ensuring thatwhen the tBASE parameter is reprogrammed the reset state machine uses thenew value for its first cycle. For the first, we explicitly forced a 0 input for anyparameter to 0 when storing that value; if this were not done, tBASE = 0 wouldresult in a zero-length side street green, tEXT = 0 would result in a zero-lengthwalk cycle, and tY EL = 0 would eliminate yellow lights altogether, all of whichwere deemed unreasonable behavior for a traffic lights or walk signals. As forthe second issue, it turned out the modified parameter value reaches the inputsof the timer early enough that no special effort was required to ensure correctfunctionality.

The time parameter memory’s implementation is given in Section 5.4.

2.2.6 State Machine

The state machine contains the core logic of the traffic controller; as such, itsfunctionality is important enough that its complete details have been expandedinto Section 2.3.

2.2.7 Traffic Light

The traffic light component converts a numeric traffic light input into the setof three outputs corresponding to the red, yellow, and green lights. Strictlyspeaking, this component could have been folded into the state machine withoutdifficulty, but it was kept as its own component for conceptual clarity.

11

Page 12: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

2.3 The Traffic Controller State Machine

The state machine underlying the traffic controller defines the core logic in thetraffic controller; see Section 5.8 for its implementation.

The state machine used in the traffic controller contains eight states: threefor a main-street green light (two of which correspond to a variable-length secondhalf of the main green light), one for a main-street yellow, one for a walk signal,two for a side-street green light (one of which is an extended period of greennessonly encountered when the traffic sensor is high at the end of the normal greenperiod), and one for a side-street yellow. The precise definitions of all states,their outputs and durations, and their transitions and associated conditions aregiven in Figure 5.

Figure 5: The states of the traffic controller, the conditions which determinethe next state, and the duration and outputs for each state. The initial state isSTART MAIN GREEN.

12

Page 13: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

In addition to the system-wide clock, the state machine takes as inputsreset, trafficSensor, pendingWalk, and expired signals. The reset signalimmediately and unconditionally returns the state machine to its initial state,START MAIN GREEN. The trafficSensor input is used in two places: first, todetermine whether the main street receives a green light of length tBASE +tEXT

or of length 2tBASE , and second, to determine whether the side traffic receivesa green light of length tBASE + tEXT or merely of length tBASE . pendingWalkis used at the end of the main-street yellow light to determine whether a walkcycle should be introduced instead of immediately transitioning to a side-streetgreen light. expired is used to determine when the transition to the next stateshould occur; it is the output from the controller’s timer and is triggered whenthe time requested of the timer by the state machine completes.

The state machine’s “internal” outputs (that is, outputs which are not out-puts of the traffic controller as a whole, such as the signals for the trafficlights; we also include the debugging-only state[2:0] output) are startTimer,timeParameter[1:0], and resetWalk. startTimer and timeParameter[1:0]are used to start the circuit with the time stored in the desired parameter.startTimer is asserted high at the start of each state, and timeParameter[1:0]encodes the desired time parameter, with big-endian 0, 1, and 2 correspondingto tBASE , tEXT , and tY EL, respectively. resetWalk is used at the end of thewalk cycle to reset the pendingWalk output of the walk register (which is alsoan input to the state machine), signaling that the walk request generated whenthe walk button was most recently pushed has been serviced.

Figure 6: Simulation of the state machine using custom waveforms

To illustrate how the state machine works, suppose we are in the middleof the START MAIN GREEN state. At the positive edge of the circuit clock, weset the “external” outputs (that is, the states of the traffic lights) of the state

13

Page 14: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

machine based on the current state, which is stored in a register in the statemachine. Also, since we’re in the middle of a state, we assert startTimer low toensure that the timer isn’t accidentally set again. We continue doing this at eachpositive clock edge until expired is asserted high. At this point, the currentstate is ending, and the state machine transitions to a new state. In most casesthe next state is determined unconditionally; for the START MAIN GREEN state,however, the next state is a function of trafficSensor. Consequently, we checkthe value of trafficSensor; if it is high, CONT MAIN GREEN TRAFFIC is loadedas the next state, and if it is low, CONT MAIN GREEN NO TRAFFIC is loaded as thenext state. The state machine now chooses the time parameter correspondingto the length of time of the next state as was just determined and encodes it astimeParameter, and it asserts startTimer high to start the timer for the nextstate’s duration. This basic cycle occurs for every state in the state machine,with state, time parameter, and outputs being chosen according to the statesinvolved.

3 Testing and Debugging

Testing of the traffic controller and its constituent components consisted of twophases: component-level simulation tests and overall integration tests performedby hand.

Component-level simulation tests consisted of writing Verilog test moduleswhich contained an instance of the tested component, creating a clock and usingit to drive the circuit, generating sets of inputs for the component over time,and checking the outputs and asserting that they had the correct values. Ex-amples of such tests included the Verilog given in Section 5.11, Section 5.12,and Section 5.14 (see all Verilog files whose names begin with “Test” for thefull list). These tests were instantiated in a single test file, TestAll.v in Sec-tion 5.10, and were periodically run by launching ModelSim from the XilinxProject Navigator and executing the commands vsim TestAll and run witha sufficiently large time to completely execute all tests. (While not in the labusing the free Icarus Verilog implementation to compile tests and run them lo-cally also worked well, albeit with less speed than the machines in the lab couldprovide.) While the tests were extremely accurate, they required a considerableamount of time and effort to construct, so most of the rest of the tests weremanual functionality tests. An additional disadvantage which may prove im-portant in the future is that such tests may not be able to expose timing bugswhere inter-component propagation times will cause race conditions; thankfully,no such situations occurred in this lab.

Manual tests involved loading the code onto the labkit, toggling inputs, andcomparing the outputs with expected behavior. This worked well for detecting“thinkos” where the problem and solution were obvious, but it required a lengthycompilation and loading process which reduced the effectiveness of the strategy.

The largest problem with manual functionality tests, however, was that theygave less insight into bugs in the controller. In particular, the most annoying

14

Page 15: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

bug in the controller required writing a Verilog test module. The bug was thatthe timer module set expired high when the count reached 0, not when itreached 1, for reasons described earlier in this report and in comments in theimplementation itself.

In retrospect, written tests, even though they required a large amount of timeto write, were the way to go in most cases. They are insufficient for integrationtesting, but the controller would have required less effort to implement hadevery component had a complete Verilog test module written. Given more timewriting tests for the remaining untested modules would be a priority to ensurethe correctness of future modifications could be most easily verified. Anotherchange to make in the future will be to use ModelSim more with input waveformsgenerated “on the fly”, because doing so is much faster than compiling the codeand copying it to the labkit for manual testing.

One additional debugging strategy which was particularly useful in testingthe controller was to add an additional output showing the current state ofthe internal state machine; this information was the state[2:0] output of thecontroller. Running this value into an LED and displaying the number gavethe current state of the controller. The wiring to do this is in Section 5.1; seethe HexLED instance there, which is wired as an output of the traffic controller.This strategy of displaying state-based data will be useful in future labs

4 Conclusions

The goals of this lab were to construct a small but complex digital system in Ver-ilog and gain experience debugging and testing digital systems using simulatorsand other tools.

Construction of the traffic controller was a success. The final product hasno known bugs, employs an elegant and compact design, has verbose commentsand module-level documentation, and has several automatable tests for use inensuring continuing correct behavior in the face of future changes. It also pro-vided exposure to key concepts for future labs: the use of state machines tocontrol behavior and outputs, measuring time using embedding counters, andthe concept of start and finish signals such as startTimer and expired. De-signing in hardware is significantly different from designing in software, andlearning how to deal with the differences between the two using these conceptswill be important in future labs.

Simulation proved to be a key component in debugging the traffic controller,particularly through its use with Verilog test modules. These modules proveduseful in detecting some of the more insidious bugs in the controller. Unfortu-nately, in using simulation to detect bugs too much emphasis was placed on testmodules and not enough was placed on as-needed simulation using generatedwaveforms (partly due to the rather obtuse waveform generation user interfacein ModelSim). In future labs more emphasis will definitely be placed on in-teractive simulation, because it eliminates the compile-time delay, allows easymodification of all input values (including those which cannot be accessed by

15

Page 16: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

examining the traffic controller externally, such as internal state values), anddoesn’t require that an examined output actually be an output. For exam-ple, it is possible to examine non-output variables in the Timer module withinthe simulator, but doing so on the labkit would require making that variable anoutput of Timer, making that output an output of TrafficController, and chang-ing signatures for all test instances of both components, all of which requiresconsiderable time to do. This is the single largest thing which would be donedifferently if this lab were to be repeated.

16

Page 17: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

5 Appendix

5.1 labkit.v

1 // ///////////////////////////////////////////////////////////////////////////2 //3 // 6.111 FPGA Labkit -- Template Toplevel Module4 //5 // For Labkit Revision 0046 //7 //8 // Created: October 31, 2004 , from revision 003 file9 // Author: Nathan Ickes

10 //11 // ///////////////////////////////////////////////////////////////////////////1213 /**14 * Generates bits for a given hex digit corresponding to segments of a15 * 7-segment numeric LED.16 *17 * @param hexDigit [3:0]18 * the desired big -endian hex digit19 * @param segments [6:0]20 * bits specifying on/off (1/0) for each segment of a numeric LED:21 *22 * __ 023 * | | 5 124 * -- corresponds to these bits of segments: 625 * | | 4 226 * -- 327 */28 module HexLED(hexDigit , segments );29 input [3:0] hexDigit;30 output [6:0] segments;31 reg [6:0] segments;3233 always @ (hexDigit [3:0])34 begin35 case (hexDigit [3:0])36 4’h0: segments [6:0] = 7’b0111111;37 4’h1: segments [6:0] = 7’b0000110;38 4’h2: segments [6:0] = 7’b1011011;39 4’h3: segments [6:0] = 7’b1001111;40 4’h4: segments [6:0] = 7’b1100110;41 4’h5: segments [6:0] = 7’b1101101;42 4’h6: segments [6:0] = 7’b1111101;43 4’h7: segments [6:0] = 7’b0000111;44 4’h8: segments [6:0] = 7’b1111111;45 4’h9: segments [6:0] = 7’b1101111;46 4’hA: segments [6:0] = 7’b1110111;47 4’hB: segments [6:0] = 7’b1111100;48 4’hC: segments [6:0] = 7’b1011000;49 4’hD: segments [6:0] = 7’b1011110;50 4’hE: segments [6:0] = 7’b1111001;51 4’hF: segments [6:0] = 7’b1110001;52 endcase53 end5455 endmodule565758 module labkit (beep , audio_reset_b , ac97_sdata_out , ac97_sdata_in ,59 ac97_synch , ac97_bit_clock ,6061 vga_out_red , vga_out_green , vga_out_blue , vga_out_sync_b ,62 vga_out_blank_b , vga_out_pixel_clock , vga_out_hsync ,63 vga_out_vsync ,

17

Page 18: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

6465 tv_out_ycrcb , tv_out_reset_b , tv_out_clock , tv_out_i2c_clock ,66 tv_out_i2c_data , tv_out_pal_ntsc , tv_out_hsync_b ,67 tv_out_vsync_b , tv_out_blank_b , tv_out_subcar_reset ,6869 tv_in_ycrcb , tv_in_data_valid , tv_in_line_clock1 ,70 tv_in_line_clock2 , tv_in_aef , tv_in_hff , tv_in_aff ,71 tv_in_i2c_clock , tv_in_i2c_data , tv_in_fifo_read ,72 tv_in_fifo_clock , tv_in_iso , tv_in_reset_b , tv_in_clock ,7374 ram0_data , ram0_address , ram0_adv_ld , ram0_clk , ram0_cen_b ,75 ram0_ce_b , ram0_oe_b , ram0_we_b , ram0_bwe_b ,7677 ram1_data , ram1_address , ram1_adv_ld , ram1_clk , ram1_cen_b ,78 ram1_ce_b , ram1_oe_b , ram1_we_b , ram1_bwe_b ,7980 clock_feedback_out , clock_feedback_in ,8182 flash_data , flash_address , flash_ce_b , flash_oe_b , flash_we_b ,83 flash_reset_b , flash_sts , flash_byte_b ,8485 rs232_txd , rs232_rxd , rs232_rts , rs232_cts ,8687 mouse_clock , mouse_data , keyboard_clock , keyboard_data ,8889 clock_27mhz , clock1 , clock2 ,9091 disp_blank , disp_data_out , disp_clock , disp_rs , disp_ce_b ,92 disp_reset_b , disp_data_in ,9394 button0 , button1 , button2 , button3 , button_enter ,95 button_right ,96 button_left , button_down , button_up ,9798 switch ,99

100 led ,101102 user1 , user2 , user3 , user4 ,103104 daughtercard ,105106 systemace_data , systemace_address , systemace_ce_b ,107 systemace_we_b , systemace_oe_b , systemace_irq ,108 systemace_mpbrdy ,109110 analyzer1_data , analyzer1_clock ,111 analyzer2_data , analyzer2_clock ,112 analyzer3_data , analyzer3_clock ,113 analyzer4_data , analyzer4_clock );114115 output beep , audio_reset_b , ac97_synch , ac97_sdata_out;116 input ac97_bit_clock , ac97_sdata_in;117118 output [7:0] vga_out_red , vga_out_green , vga_out_blue;119 output vga_out_sync_b , vga_out_blank_b , vga_out_pixel_clock ,120 vga_out_hsync , vga_out_vsync;121122 output [9:0] tv_out_ycrcb;123 output tv_out_reset_b , tv_out_clock , tv_out_i2c_clock , tv_out_i2c_data ,124 tv_out_pal_ntsc , tv_out_hsync_b , tv_out_vsync_b , tv_out_blank_b ,125 tv_out_subcar_reset;126127 input [19:0] tv_in_ycrcb;128 input tv_in_data_valid , tv_in_line_clock1 , tv_in_line_clock2 , tv_in_aef ,129 tv_in_hff , tv_in_aff;130 output tv_in_i2c_clock , tv_in_fifo_read , tv_in_fifo_clock , tv_in_iso ,131 tv_in_reset_b , tv_in_clock;

18

Page 19: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

132 inout tv_in_i2c_data;133134 inout [35:0] ram0_data;135 output [18:0] ram0_address;136 output ram0_adv_ld , ram0_clk , ram0_cen_b , ram0_ce_b , ram0_oe_b , ram0_we_b;137 output [3:0] ram0_bwe_b;138139 inout [35:0] ram1_data;140 output [18:0] ram1_address;141 output ram1_adv_ld , ram1_clk , ram1_cen_b , ram1_ce_b , ram1_oe_b , ram1_we_b;142 output [3:0] ram1_bwe_b;143144 input clock_feedback_in;145 output clock_feedback_out;146147 inout [15:0] flash_data;148 output [23:0] flash_address;149 output flash_ce_b , flash_oe_b , flash_we_b , flash_reset_b , flash_byte_b;150 input flash_sts;151152 output rs232_txd , rs232_rts;153 input rs232_rxd , rs232_cts;154155 input mouse_clock , mouse_data , keyboard_clock , keyboard_data;156157 input clock_27mhz , clock1 , clock2;158159 output disp_blank , disp_clock , disp_rs , disp_ce_b , disp_reset_b;160 input disp_data_in;161 output disp_data_out;162163 input button0 , button1 , button2 , button3 , button_enter , button_right ,164 button_left , button_down , button_up;165 input [7:0] switch;166 output [7:0] led;167168 inout [31:0] user1 , user2 , user3 , user4;169170 inout [43:0] daughtercard;171172 inout [15:0] systemace_data;173 output [6:0] systemace_address;174 output systemace_ce_b , systemace_we_b , systemace_oe_b;175 input systemace_irq , systemace_mpbrdy;176177 output [15:0] analyzer1_data , analyzer2_data , analyzer3_data ,178 analyzer4_data;179 output analyzer1_clock , analyzer2_clock , analyzer3_clock , analyzer4_clock;180181 // /////////////////////////////////////////////////////////////////////////182 //183 // I/O Assignments184 //185 // /////////////////////////////////////////////////////////////////////////186187 // Audio Input and Output188 assign beep= 1’b0;189 assign audio_reset_b = 1’b0;190 assign ac97_synch = 1’b0;191 assign ac97_sdata_out = 1’b0;192 // ac97_sdata_in is an input193194 // VGA Output195 assign vga_out_red = 8’h0;196 assign vga_out_green = 8’h0;197 assign vga_out_blue = 8’h0;198 assign vga_out_sync_b = 1’b1;199 assign vga_out_blank_b = 1’b1;

19

Page 20: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

200 assign vga_out_pixel_clock = 1’b0;201 assign vga_out_hsync = 1’b0;202 assign vga_out_vsync = 1’b0;203204 // Video Output205 assign tv_out_ycrcb = 10’h0;206 assign tv_out_reset_b = 1’b0;207 assign tv_out_clock = 1’b0;208 assign tv_out_i2c_clock = 1’b0;209 assign tv_out_i2c_data = 1’b0;210 assign tv_out_pal_ntsc = 1’b0;211 assign tv_out_hsync_b = 1’b1;212 assign tv_out_vsync_b = 1’b1;213 assign tv_out_blank_b = 1’b1;214 assign tv_out_subcar_reset = 1’b0;215216 // Video Input217 assign tv_in_i2c_clock = 1’b0;218 assign tv_in_fifo_read = 1’b0;219 assign tv_in_fifo_clock = 1’b0;220 assign tv_in_iso = 1’b0;221 assign tv_in_reset_b = 1’b0;222 assign tv_in_clock = 1’b0;223 assign tv_in_i2c_data = 1’bZ;224 // tv_in_ycrcb , tv_in_data_valid , tv_in_line_clock1 , tv_in_line_clock2 ,225 // tv_in_aef , tv_in_hff , and tv_in_aff are inputs226227 // SRAMs228 assign ram0_data = 36’hZ;229 assign ram0_address = 19’h0;230 assign ram0_adv_ld = 1’b0;231 assign ram0_clk = 1’b0;232 assign ram0_cen_b = 1’b1;233 assign ram0_ce_b = 1’b1;234 assign ram0_oe_b = 1’b1;235 assign ram0_we_b = 1’b1;236 assign ram0_bwe_b = 4’hF;237 assign ram1_data = 36’hZ;238 assign ram1_address = 19’h0;239 assign ram1_adv_ld = 1’b0;240 assign ram1_clk = 1’b0;241 assign ram1_cen_b = 1’b1;242 assign ram1_ce_b = 1’b1;243 assign ram1_oe_b = 1’b1;244 assign ram1_we_b = 1’b1;245 assign ram1_bwe_b = 4’hF;246 assign clock_feedback_out = 1’b0;247 // clock_feedback_in is an input248249 // Flash ROM250 assign flash_data = 16’hZ;251 assign flash_address = 24’h0;252 assign flash_ce_b = 1’b1;253 assign flash_oe_b = 1’b1;254 assign flash_we_b = 1’b1;255 assign flash_reset_b = 1’b0;256 assign flash_byte_b = 1’b1;257 // flash_sts is an input258259 // RS -232 Interface260 assign rs232_txd = 1’b1;261 assign rs232_rts = 1’b1;262 // rs232_rxd and rs232_cts are inputs263264 // PS/2 Ports265 // mouse_clock , mouse_data , keyboard_clock , and keyboard_data are inputs266267 // LED Displays

20

Page 21: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

268 assign disp_blank = 1’b1;269 assign disp_clock = 1’b0;270 assign disp_rs = 1’b0;271 assign disp_ce_b = 1’b1;272 assign disp_reset_b = 1’b0;273 assign disp_data_out = 1’b0;274 // disp_data_in is an input275276 // Buttons , Switches , and Individual LEDs277 // assign led = 8’hFF;278 assign led [1] = 1’b1;279 // button0 , button1 , button2 , button3 , button_enter , button_right ,280 // button_left , button_down , button_up , and switches are inputs281282 // User I/Os283 assign user1 = 32’hZ;284 assign user2 = 32’hZ;285 assign user3 = 32’hZ;286 assign user4 = 32’hZ;287288 // Daughtercard Connectors289 assign daughtercard = 44’hZ;290291 // SystemACE Microprocessor Port292 assign systemace_data = 16’hZ;293 assign systemace_address = 7’h0;294 assign systemace_ce_b = 1’b1;295 assign systemace_we_b = 1’b1;296 assign systemace_oe_b = 1’b1;297 // systemace_irq and systemace_mpbrdy are inputs298299 // Logic Analyzer300 assign analyzer1_data = 16’h0;301 assign analyzer1_clock = 1’b1;302 assign analyzer2_data = 16’h0;303 assign analyzer2_clock = 1’b1;304 assign analyzer3_data = 16’h0;305 assign analyzer3_clock = 1’b1;306 assign analyzer4_data = 16’h0;307 assign analyzer4_clock = 1’b1;308309 // set up traffic controller310 /**311 *312 * User interface :313 *314 * reset button 0315 * walk button Enter button316 * reprogram button 3317 * traffic sensor switch 7318 * time selector switches 6 and 5319 * time value switches 3-0320 *321 * main light leds 7-5 (red -green)322 * side light leds 4-2 (red -green)323 * walk light led 0324 */325 wire [2:0] stateWire;326 TrafficController intersection (.clk(clock_27mhz),327 .reset (~ button0), // inverted328 .trafficSensor(switch [7]),329 .walkRequest (~ button_enter), // inverted330 .reprogram (~ button3), // inverted331 .timeSelector(switch [6:5]) ,332 .value(switch [3:0]) ,333 .redMain(led[7]),334 .yellowMain(led[6]),335 .greenMain(led[5]),

21

Page 22: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

336 .redSide(led[4]),337 .yellowSide(led[3]),338 .greenSide(led[2]),339 .walkLight(led[0]),340 .state(stateWire ));341342 HexLED st(. hexDigit ({1’b0 , stateWire}),343 .segments(user3 [31:25]));344 endmodule

5.2 Debouncer.v

1 /**2 * A circuit which converts a noisy signal which initially fluctuates before3 * settling to a high state into a single high signal for as long as the4 * noisy signal then remains high.5 *6 *7 * INPUTS8 *9 * @param clk

10 * a clock used to measure time from when the noisy signal is asserted high11 * until it is consistently high for the desired length of time12 * @param reset13 * resets the internal counter to 0 XXX anything else?14 * @param noisy15 * a signal which must be held high for a certain length of time before16 * clean is asserted high17 *18 *19 * OUTPUTS20 *21 * @param clean22 * low except when noisy has been held consistently high for the desired23 * length of time , at which point it will remain high until noisy becomes24 * low25 */26 module Debouncer(clk ,27 reset , noisy ,28 clean );29 parameter DELAY = 270000; // .01 sec with a 27 Mhz clock30 input reset , clk , noisy;31 output clean;3233 reg [18:0] count;34 reg new , clean;3536 always @(posedge clk)37 if (reset)38 begin39 count <= 0;40 new <= noisy;41 clean <= noisy;42 end43 else if (noisy != new)44 begin45 new <= noisy;46 count <= 0;47 end48 else if (count == DELAY)49 clean <= new;50 else51 count <= count + 1;5253 endmodule

22

Page 23: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

5.3 Synchronizer.v

1 /**2 * A circuit which synchronizes an external signal with a clock.3 *4 *5 * INPUTS6 *7 * @param clk8 * the clock with which to synchronize9 * @param in

10 * the external signal11 *12 *13 * OUTPUTS14 *15 * @param out16 * the in signal synchronized with clk17 */18 module Synchronizer(clk ,19 in ,20 out);21 parameter NSYNC = 2; // number of sync flops. must be >= 222 input clk;23 input in;24 output out;2526 reg [NSYNC -2:0] sync;27 reg out;2829 always @ (posedge clk)30 begin31 {out ,sync} <= {sync[NSYNC -2:0] ,in};32 end33 endmodule

5.4 TimeParameters.v

1 /**2 * A small , programmable memory device which stores three time values: tBASE ,3 * tEXT , and tYEL. The values may be individually programmed by setting4 * value to the desired value for the parameter to change , setting selector5 * to select the desired parameter to change , and setting reprogram to 1.6 * These values are reset to their default values ( currently 6, 3, and 27 * respectively ) when (reset === 1).8 *9 *

10 * INPUTS11 *12 * @param clk13 * a clock whose positive edge triggers this circuit14 * @param selector [1:0]15 * determines which time parameter may be mutated by setting reprogram .16 * Possible values are 0 => tBASE , 1 => tEXT , and 2 => tYEL. Results when17 * setting this value to 3 are undefined .18 * @param value [3:0]19 * the big -endian value which will be stored in this if reprogram is20 * asserted; note , however , that there exist situations for each parameter21 * where a value of 0 doesn ’t make sense , so if this is 0 and reprogram is22 * asserted , the parameter indicated by selector will actually be set to 123 * @param reprogram24 * indicates when time parameters should be changed; set to 1 when you wish25 * to change the parameter indicated by selector to value26 * @param reset27 * resets all parameters to their default values28 *29 *

23

Page 24: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

30 * OUTPUTS31 *32 * @param tBASE [3:0]33 * the current value of tBASE , in big -endian format34 * @param tEXT [3:0]35 * the current value of tEXT , in big -endian format36 * @param tYEL [3:0]37 * the current value of tYEL , in big -endian format38 */39 module TimeParameters(clk , selector , value , reprogram , reset ,40 tBASE , tEXT , tYEL);41 input clk;42 input [1:0] selector;43 input [3:0] value;44 input reprogram , reset;45 output [3:0] tBASE , tEXT , tYEL;4647 reg [3:0] tBASE , tEXT , tYEL;4849 // values of selector for the different inputs50 parameter BASE_SELECT = 2’b0;51 parameter EXT_SELECT = 2’b1;52 parameter YEL_SELECT = 2’b10;5354 // default time parameter settings55 parameter DEFAULT_BASE = 4’b0110;56 parameter DEFAULT_EXT = 4’b0011;57 parameter DEFAULT_YEL = 4’b0010;5859 // maximum value for any time parameter60 parameter MAX_TIME = 4’b1111;61 parameter ZERO_TIME = 4’b0000;6263 always @ (posedge clk)64 begin65 if (reset)66 begin67 tBASE <= DEFAULT_BASE;68 tEXT <= DEFAULT_EXT;69 tYEL <= DEFAULT_YEL;70 end71 else if (reprogram)72 begin73 // Reprogram the appropriate value; note that we explicitly disallow74 // a value of 0 for any parameter and replace it with a small number:75 //76 // tYEL77 // - a traffic light having a yellow -light cycle time of 0s would be78 // a VERY BAD IDEA for obvious reasons79 // tBASE80 // - when the traffic sensor is low , Main St. gets a green for81 // 2*tBASE , so if tBASE ==0 and there ’s no further traffic on Side82 // St. after their initial green , Main St. traffic is stuck83 // tEXT84 // - the walk light is lit for tEXT time , so if we allow 0s for tEXT ,85 // pedestrians are forced to jaywalk86 //87 // Despite this forbidding of 0, the circuit has been tested to still88 // work correctly if we were to remove the 0=>1 forcing code below89 // and replace the assignments with simply "value ".90 case (selector)91 BASE_SELECT: tBASE <= (value !== ZERO_TIME) ? value : 4’b0001;92 EXT_SELECT: tEXT <= (value !== ZERO_TIME) ? value : 4’b0001;93 YEL_SELECT: tYEL <= (value !== ZERO_TIME) ? value : 4’b0001;94 default:95 // Try to make logic errors elsewhere as obvious as possible;96 // note that this also takes effect if the human operator97 // accidentally sets the selector to the wrong value , but we ’re

24

Page 25: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

98 // not optimizing for human interaction with the device at this99 // level

100 begin101 tBASE <= MAX_TIME;102 tEXT <= MAX_TIME;103 tYEL <= MAX_TIME;104 end105 endcase106 end107 end108 endmodule

5.5 Timer.v

1 /**2 * A programmable timer in 1-second intervals from 0 to 15 seconds. This3 * clock should be used for one -shot timing; behavior after expired is4 * asserted high at the end of the timing of a length of time is undefined .5 *6 *7 * INPUTS8 *9 * @param clk

10 * a 27 MHz clock11 * @param reset12 * assert high to reset all timing functionality13 * @param timeParameters14 * the values of the three programmable timing parameters :15 * {tBASE [3:0] , tEXT [3:0] , tYEL [3:0]}16 * @param selector [1:0]17 * selects which of the three timing parameters should be used when18 * startTimer is asserted: big -endian values map as follows: 0 => tBASE ,19 * 1 => tEXT , 2 => tYEL; 3 => undefined behavior20 * @param startTimer21 * assert high when the timer should be started using the time indicated by22 * selector and the appropriate value from timeParameters23 *24 *25 * OUTPUTS26 *27 * @param expired28 * asserted to 1 for one clock cycle when the timer initiated by asserting29 * startTimer high has expired30 */31 module Timer(clk ,32 reset ,33 timeParameters , selector ,34 startTimer ,35 expired );36 input clk;37 input reset;38 input [11:0] timeParameters;39 input [1:0] selector;40 input startTimer;4142 output expired;43 reg expired;4445 // contains the current count until expired should be asserted46 reg [3:0] count;4748 // current 27 MHz count49 reg [24:0] clkCycleCount;5051 // max/min values of count52 parameter MAX_COUNT = 4’b1111;53 parameter ZERO_COUNT = 4’b0000;

25

Page 26: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

54 parameter ONE_COUNT = 4’b0001;5556 // values for the time parameter selector57 parameter BASE_SELECT = 2’b00;58 parameter EXT_SELECT = 2’b01;59 parameter YEL_SELECT = 2’b10;6061 // values used to determine when 1s is up62 parameter CLK_COUNT_AFTER_ONE_SECOND = 25’ d26_999_999;63 parameter CLK_COUNT_ZERO = 25’b0;6465 always @ (posedge clk)66 begin67 // *not* expired or cleared unless explicitly overridden68 expired <= 0;6970 // 1s timer increments from 0 to 27e6 -1 and repeats unless we ’re being71 // reset72 if (clkCycleCount == CLK_COUNT_AFTER_ONE_SECOND ||73 reset == 1)74 clkCycleCount <= CLK_COUNT_ZERO;75 else76 clkCycleCount <= clkCycleCount + 1;7778 // note ordering: reset overrides startTimer , which overrides 1Hz events79 if (reset)80 begin81 expired <= 0;82 count <= MAX_COUNT; // for debugging83 end84 else if (startTimer)85 begin86 expired <= 0;87 clkCycleCount <= CLK_COUNT_ZERO;8889 // what length of time do we want?90 // note that we must handle 0-length cases by setting expired91 case (selector)92 BASE_SELECT:93 begin94 if (timeParameters [11:8] == 4’b0000)95 begin96 expired <= 1;97 count <= MAX_COUNT; // catch bugs98 end99 else

100 count <= timeParameters [11:8];101 end102103 EXT_SELECT:104 begin105 if (timeParameters [7:4] == 4’b0000)106 begin107 expired <= 1;108 count <= MAX_COUNT; // catch bugs109 end110 else111 count <= timeParameters [7:4];112 end113114 YEL_SELECT:115 begin116 if (timeParameters [3:0] == 4’b0000)117 begin118 expired <= 1;119 count <= MAX_COUNT; // catch bugs120 end121 else

26

Page 27: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

122 count <= timeParameters [3:0];123 end124125 default:126 count <= MAX_COUNT; // catch bugs127 endcase128 end129 else if (clkCycleCount == CLK_COUNT_AFTER_ONE_SECOND)130 begin131 // note that we check for 1 because count is only decremented to 0132 // *after* the current cycle -- at startTimer , if we set count to 1,133 // then the next time we hit this is one second later -- exactly when134 // the timer should expire135 expired <= (count == ONE_COUNT );136137 // always do this (if count ==1, then purely for debugging purposes)138 count <= count - 1;139 end140 end141 endmodule

5.6 TrafficController.v

1 /**2 * A complete traffic controller for the intersection of a major street and a3 * minor state.4 *5 *6 * INPUTS7 *8 * @param clk9 * a clock whose positive edge triggers this circuit

10 * @param reset11 * assert high when this circuit must be initialized , assert low to12 * complete initialization13 * @param trafficSensor14 * high when traffic is traveling over the intersection ’s traffic sensor15 * @param walkRequest16 * a signal which should be asserted high to signal that a walk request17 * must be serviced; need not be kept high to induce a walk light18 * @param reprogram19 * assert high to reprogram the time parameter indicated by selector to the20 * value indicated by value; this also resets this controller to its21 * initial state (modulo the changed time parameter )22 * @param timeSelector [1:0]23 * selects the time parameter which will be changed to value when reprogram24 * is asserted25 * @param value [3:0]26 * the value to which the given time parameter may be reprogrammed27 *28 *29 * OUTPUTS30 *31 * @param redMain , yellowMain , greenMain32 * outputs which , when asserted low , should turn the corresponding light33 * on (and off when asserted high)34 * @param redSide , yellowSide , greenSide35 * outputs which , when asserted low , should turn the corresponding light on36 * (and off when asserted high)37 * @param walkLight38 * when asserted low , should turn on the walk light (and when asserted39 * high , should turn it off)40 * @param state [2:0]41 * displays the internal state of the state machine underlying this; for42 * debugging purposes only -- do not use the values provided by this for43 * any other purpose44 */

27

Page 28: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

45 module TrafficController(clk ,46 reset ,47 trafficSensor , walkRequest ,48 reprogram , timeSelector , value ,49 redMain , yellowMain , greenMain ,50 redSide , yellowSide , greenSide ,51 walkLight ,52 state );53 input clk;54 input reset;5556 input trafficSensor , walkRequest;57 input reprogram;58 input [1:0] timeSelector;59 input [3:0] value;6061 output redMain , yellowMain , greenMain;62 output redSide , yellowSide , greenSide;63 output walkLight;6465 output [2:0] state;6667 // sync ’d signals from inputs68 wire resetSync , trafficSensorSync , walkRequestSync , reprogramSync;6970 // internal wires71 wire walkReset , pendingWalk;72 wire startTimer , expired;73 wire [3:0] tBASE , tEXT , tYEL;74 wire [1:0] fsmSelector;7576 wire [1:0] mainLight , sideLight;7778 // for debugging only79 wire [2:0] state;8081 // sync external signals with clk82 Synchronizer syncTrafficSensor (.clk(clk),83 .in(trafficSensor),84 .out(trafficSensorSync ));8586 // debounce and sync push -button signals87 Debouncer syncReset (.clk(clk),88 .reset (0), .noisy(reset),89 .clean(resetSync ));90 Debouncer syncWalkRequest (.clk(clk),91 .reset (0), .noisy(walkRequest),92 .clean(walkRequestSync ));93 Debouncer syncReprogram (.clk(clk),94 .reset (0), .noisy(reprogram),95 .clean(reprogramSync ));9697 // walk register98 WalkRegister wr(.clk(clk),99 .walkPush(walkRequestSync),

100 .reset(walkReset),101 .pendingWalk(pendingWalk ));102103 // FSM104 TrafficState fsm(.clk(clk),105 .reset(resetSync),106 .trafficSensor(trafficSensorSync),107 .pendingWalk(pendingWalk),108 .reprogram(reprogramSync),109 .expired(expired),110 .startTimer(startTimer),111 .timeParameter(fsmSelector),112 .resetWalk(walkReset),

28

Page 29: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

113 .mainLight(mainLight),114 .sideLight(sideLight),115 .walkLight(walkLight),116117 .state(state ));118119 // the traffic lights120 TrafficLight main(. signal(mainLight),121 .red(redMain), .yellow(yellowMain), .green(greenMain ));122 TrafficLight side(. signal(sideLight),123 .red(redSide), .yellow(yellowSide), .green(greenSide ));124125 // time parameter storage126 TimeParameters times (.clk(clk),127 .selector(timeSelector),128 .value(value),129 .reprogram(reprogram),130 .reset(resetSync),131 .tBASE(tBASE),132 .tEXT(tEXT),133 .tYEL(tYEL ));134135 // timer136 Timer timer (.clk(clk),137 .reset(resetSync),138 .timeParameters ({tBASE [3:0], tEXT [3:0] , tYEL [3:0]}) ,139 .selector(fsmSelector [1:0]) ,140 .startTimer(startTimer),141 .expired(expired ));142 endmodule

5.7 TrafficLight.v

1 /**2 * Converts a traffic signal encoding into a set of three lights , lighting3 * the appropriate light for each encoding.4 *5 *6 * INPUTS7 *8 * @param signal [1:0]9 * the signal to light; 0 => red , 1 => yellow , 2 => green; results when

10 * (signal === 3) are undefined11 *12 *13 * OUTPUTS14 *15 * @param red16 * the red traffic light; 0 is on , 1 is off17 * @param yellow18 * the yellow traffic light; 0 is on , 1 is off19 * @param green20 * the green traffic light; 0 is on , 1 is off21 */22 module TrafficLight(signal ,23 red , yellow , green);24 input [1:0] signal;25 output red , yellow , green;2627 reg red , yellow , green;2829 parameter RED_LIGHT = 2’b0;30 parameter YELLOW_LIGHT = 2’b1;31 parameter GREEN_LIGHT = 2’b10;3233 // note that these values are reversed from the norm (where on/off ==1/0)34 parameter ON = 0;

29

Page 30: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

35 parameter OFF = 1;3637 always @ (signal)38 begin39 case (signal)40 RED_LIGHT:41 begin42 red <= ON;43 yellow <= OFF;44 green <= OFF;45 end46 YELLOW_LIGHT:47 begin48 red <= OFF;49 yellow <= ON;50 green <= OFF;51 end52 GREEN_LIGHT:53 begin54 red <= OFF;55 yellow <= OFF;56 green <= ON;57 end58 default:59 // catch logic errors60 begin61 red <= ON;62 yellow <= ON;63 green <= ON;64 end65 endcase66 end67 endmodule

5.8 TrafficState.v

1 /**2 * A state machine to manage the state of the walk light and traffic signals.3 *4 *5 * INPUTS6 *7 * @param clk8 * a clock used to trigger changes in state (when the appropriate amount of9 * time has passed , that is)

10 * @param reset11 * assert to 1 to reset the state module to its original state , and12 * otherwise leave at 013 * @param trafficSensor14 * set to 1 when Side Street has traffic and 0 when it doesn ’t15 * @param pendingWalk16 * 1 when a walk request must be serviced , 0 otherwise17 * @param expired18 * set to 1 when the timer started using startTimer and timeParameter19 * finishes , and otherwise 020 *21 *22 * OUTPUTS23 *24 * @param startTimer25 * set to 1 to start the timer indicated by timeParameter ; when the timer26 * runs to completion , expired will be asserted 127 * @param timeParameter [1:0]28 * indicates the time parameter which determines the length of the timer;29 * 0 => tBASE , 1 => tEXT , 2 => tYEL; the semantics of 3 are undefined30 * @param resetWalk31 * set this to 1 when pendingWalk should be reset to 0 (i.e., when the walk

30

Page 31: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

32 * request has been serviced33 * @param mainLight [1:0]34 * set to the state of the main light; 0 => red light , 1 => yellow light ,35 * and 2 => green light; the semantics of 3 are undefined36 * @param sideLight [1:0]37 * set to the state of the side light; 0 => red light , 1 => yellow light ,38 * and 2 => green light; the semantics of 3 are undefined39 * @param walkLight40 * 0 when the walk light should be on , 1 when it should be off41 * @param state [2:0]42 * displays the internal state of this state machine; for debugging43 * purposes only -- do not use the values provided by this for any44 * other purpose45 */46 module TrafficState(clk ,47 reset , trafficSensor , pendingWalk ,48 reprogram , expired ,49 startTimer , timeParameter , resetWalk ,50 mainLight , sideLight , walkLight ,51 state );52 input clk;53 input reset , trafficSensor , pendingWalk , reprogram , expired;5455 output startTimer;56 output [1:0] timeParameter;5758 output resetWalk;5960 output [1:0] mainLight , sideLight;61 output walkLight;6263 output [2:0] state;6465 reg startTimer;66 reg [1:0] timeParameter;67 reg resetWalk;68 reg [1:0] mainLight , sideLight;69 reg walkLight;7071 // Constants used with walkLight .72 parameter ON = 1’b0;73 parameter OFF = 1’b1;7475 /**76 * Denotes the current state of the state machine embodied in this. The77 * values for this are listed below.78 */79 reg [2:0] state;808182 /**83 * Description of states:84 *85 * START_MAIN_GREEN86 * start of green cycle for Main87 *88 * CONT_MAIN_GREEN_NO_TRAFFIC89 * continuing Main green , Side St. clear90 *91 * CONT_MAIN_GREEN_TRAFFIC92 * continuing Main green , Side St. has traffic waiting93 *94 * MAIN_YELLOW95 * yellow for Main96 *97 * PEDESTRIAN_WALK98 * walk light is on99 *

31

Page 32: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

100 * START_SIDE_GREEN101 * Side St. green light102 *103 * CONT_SIDE_GREEN_TRAFFIC104 * Side St. has traffic at end of green -- stay green longer105 *106 * SIDE_YELLOW107 * Side St. yellow light108 */109 parameter START_MAIN_GREEN = 0;110 parameter CONT_MAIN_GREEN_NO_TRAFFIC = 1;111 parameter CONT_MAIN_GREEN_TRAFFIC = 2;112 parameter MAIN_YELLOW = 3;113 parameter PEDESTRIAN_WALK = 4;114 parameter START_SIDE_GREEN = 5;115 parameter CONT_SIDE_GREEN_TRAFFIC = 6;116 parameter SIDE_YELLOW = 7;117118 // in case the number of states is ever expanded , since this can ’t119 // actually ever occur with only 3 bits of state120 parameter INVALID_STATE = 8;121122 // traffic light signal values123 parameter RED = 2’b00;124 parameter YELLOW = 2’b01;125 parameter GREEN = 2’b10;126127 // timing parameter constants128 parameter BASE_SELECT = 2’b00;129 parameter EXT_SELECT = 2’b01;130 parameter YEL_SELECT = 2’b10;131 parameter ZERO_SELECT = 2’b11;132133 always @ (posedge clk)134 begin135 // startTimer ==1 triggers timer , so must reset it if it ’s been triggered136 startTimer <= 0;137 // only want to reset walk register in one specific case138 resetWalk <= 0;139140 if (reset || reprogram)141 begin142 // set to start state -- outputs set in ~expired below143 startTimer <= 1;144 timeParameter <= BASE_SELECT;145 state <= START_MAIN_GREEN;146 end147 else if (~ expired)148 begin149 // if ~expired , then we ’re either in the middle of a state or have150 // just transitioned into one -- set the outputs for that state151 case (state)152 START_MAIN_GREEN ,153 CONT_MAIN_GREEN_NO_TRAFFIC ,154 CONT_MAIN_GREEN_TRAFFIC:155 {mainLight , sideLight , walkLight} <= {GREEN , RED , OFF};156157 MAIN_YELLOW:158 {mainLight , sideLight , walkLight} <= {YELLOW , RED , OFF};159160 PEDESTRIAN_WALK:161 {mainLight , sideLight , walkLight} <= {RED , RED , ON};162163 START_SIDE_GREEN ,164 CONT_SIDE_GREEN_TRAFFIC:165 {mainLight , sideLight , walkLight} <= {RED , GREEN , OFF};166167 SIDE_YELLOW:

32

Page 33: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

168 {mainLight , sideLight , walkLight} <= {RED , YELLOW , OFF};169170 default: // debugging171 {mainLight , sideLight , walkLight} <= {YELLOW , YELLOW , ON};172 endcase173 end174 else175 begin176 // it ’s the end of the cycle -- we ’re always transitioning177 startTimer <= 1;178179 // set next state and how long to stay in it180 case (state)181 START_MAIN_GREEN:182 begin183 if (trafficSensor)184 begin185 timeParameter <= EXT_SELECT;186 state <= CONT_MAIN_GREEN_TRAFFIC;187 end188 else189 begin190 timeParameter <= BASE_SELECT;191 state <= CONT_MAIN_GREEN_NO_TRAFFIC;192 end193 end194195 CONT_MAIN_GREEN_NO_TRAFFIC ,196 CONT_MAIN_GREEN_TRAFFIC:197 begin198 timeParameter <= YEL_SELECT;199 state <= MAIN_YELLOW;200 end201202 MAIN_YELLOW:203 begin204 if (pendingWalk)205 begin206 timeParameter <= EXT_SELECT;207 state <= PEDESTRIAN_WALK;208 end209 else210 begin211 timeParameter <= BASE_SELECT;212 state <= START_SIDE_GREEN;213 end214 end215216 PEDESTRIAN_WALK:217 begin218 timeParameter <= BASE_SELECT;219 state <= START_SIDE_GREEN;220221 // end of the walk cycle -- reset the pendingWalk flag222 resetWalk <= 1;223 end224225 START_SIDE_GREEN:226 begin227 if (trafficSensor)228 begin229 timeParameter <= EXT_SELECT;230 state <= CONT_SIDE_GREEN_TRAFFIC;231 end232 else233 begin234 timeParameter <= YEL_SELECT;235 state <= SIDE_YELLOW;

33

Page 34: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

236 end237 end238239 CONT_SIDE_GREEN_TRAFFIC:240 begin241 timeParameter <= YEL_SELECT;242 state <= SIDE_YELLOW;243 end244245 SIDE_YELLOW:246 begin247 timeParameter <= BASE_SELECT;248 state <= START_MAIN_GREEN;249 end250251 default:252 begin253 state <= INVALID_STATE; // stay here forever , hopefully !254 end255 endcase256 end257 end258259 endmodule

5.9 WalkRegister.v

1 /**2 * An implementation of a flag which is set to 1 when a walk request is3 * registered and which is reset to 0 when the request has been served.4 *5 *6 * INPUTS7 *8 * @param clk9 * the clock upon which this register is triggered

10 * @param walkPush11 * 1 when a Walk request should be registered if one doesn ’t already exist ,12 * 0 otherwise13 * @param reset14 * set this parameter to 1 to reset pendingWalk to 015 *16 *17 * OUTPUTS18 *19 * @param pendingWalk20 * indicates whether there is a walk request which needs to be served21 */22 module WalkRegister(clk ,23 walkPush , reset ,24 pendingWalk );25 input clk;26 input walkPush , reset;27 output pendingWalk;28 reg pendingWalk;2930 always @ (posedge clk)31 begin32 pendingWalk <= reset ? 0 :33 pendingWalk ? pendingWalk : walkPush;34 end35 endmodule

5.10 TestAll.v

1 // establish time units for delays used in test module

34

Page 35: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

2 ‘timescale 1 ns / 100 ps34 /**5 * A test module which runs all tests simultaneously .6 */7 module TestAll ();8 TestTimeParameters timeParameters ();9 TestWalkRegister walkRegister ();

10 TestTimer timer ();11 endmodule

5.11 TestTimeParameters.v

1 // establish time units for delays used in test module2 ‘timescale 1 ns / 100 ps34 /**5 * A small test module for TimeParameters .6 */7 module TestTimeParameters ();8 reg clk;9 reg [1:0] selector;

10 reg [3:0] value;11 reg reprogram , reset;12 wire [3:0] tBASE , tEXT , tYEL;1314 // selectors15 parameter BASE_SELECT = 2’b0;16 parameter EXT_SELECT = 2’b1;17 parameter YEL_SELECT = 2’b10;181920 // make an instance of TimeParameters21 TimeParameters test(clk , selector , value , reprogram , reset ,22 tBASE , tEXT , tYEL);2324 /**25 * Helper task to reduce typing to check that values of tBASE , tEXT , and26 * tYEL are equal to the values passed in as arguments .27 *28 * @param base29 * the expected value of tBASE30 * @param ext31 * the expected value of tEXT32 * @param yel33 * the expected value of tYEL34 * @param msg35 * a string to be displayed if the time parameters are not what they36 * should be; must be 70 or fewer characters37 */38 task assertTimes; // (base , ext , yel , msg)39 input [3:0] base , ext , yel;40 input [8*69:0] msg;4142 if (tBASE !== base ||43 tEXT !== ext ||44 tYEL !== yel)45 begin46 $display("error: %s", msg);47 $display(" expected: (%d, %d, %d)", base , ext , yel);48 $display(" actual: (%d, %d, %d)", tBASE , tEXT , tYEL);49 $stop ();50 end51 endtask5253 // clk has 50% duty cycle , 100 ns period54 initial begin

35

Page 36: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

55 clk = 0;56 forever #50 clk = ~clk;57 end5859 initial begin60 $display("Starting test of TimeParameters ...");6162 // Note: the implementation against which this test was written forced63 // zero -size time parameters to 1 (see the comment in64 // TimeParameters .v);6566 // reset the parameters67 reset = 1;68 #10069 assertTimes (6, 3, 2, "reset didn ’t set values properly!");7071 // do params retain value over time?72 reset = 0;73 #10074 assertTimes (6, 3, 2, "reset didn ’t set values properly!");7576 // only changing value shouldn ’t affect parameters77 value = 4’b1111;78 #10079 assertTimes (6, 3, 2, "haven ’t reprogram ’d yet!");8081 value = 4’b1010;82 #10083 assertTimes (6, 3, 2, "haven ’t reprogram ’d yet!");8485 // changing selector shouldn ’t affect parameters86 selector = 2’b01;87 #10088 assertTimes (6, 3, 2, "haven ’t reprogram ’d yet!");8990 selector = 2’b11;91 #10092 assertTimes (6, 3, 2, "haven ’t reprogram ’d yet!");9394 selector = 2’b00;95 #10096 assertTimes (6, 3, 2, "haven ’t reprogram ’d yet!");9798 // now test setting values99

100 // setting tBASE101 selector = BASE_SELECT;102103 value = 4’d12;104 reprogram = 1;105 #100106 assertTimes (12, 3, 2, "tBASE not set correctly!");107108 value = 4’d6;109 reprogram = 1;110 #100111 assertTimes (6, 3, 2, "tBASE not manually set to default correctly!");112113 value = 4’d9;114 reprogram = 0;115 #100116 assertTimes (6, 3, 2, "tBASE set when ~reprogram!");117118 value = 4’d0;119 reprogram = 1;120 #100121 // tBASE ==0 means that with no side traffic , main traffic never gets a122 // green

36

Page 37: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

123 assertTimes (1, 3, 2, "tBASE not set correctly!");124125126 // setting tEXT127 selector = EXT_SELECT;128129 value = 4’d12;130 reprogram = 1;131 #100132 assertTimes (1, 12, 2, "tEXT not set correctly!");133134 value = 4’d3;135 reprogram = 1;136 #100137 assertTimes (1, 3, 2, "tEXT not manually set to default correctly!");138139 value = 4’d9;140 reprogram = 0;141 #100142 assertTimes (1, 3, 2, "tEXT set when ~reprogram!");143144 value = 4’d0;145 reprogram = 1;146 #100147 // tEXT is forced to 1 when it ’s 0, because otherwise the walk light will148 // never be lit149 assertTimes (1, 1, 2, "tEXT not set correctly!");150151152 // setting tYEL153 selector = YEL_SELECT;154155 value = 4’d12;156 reprogram = 1;157 #100158 assertTimes (1, 1, 12, "tYEL not set correctly!");159160 value = 4’d2;161 reprogram = 1;162 #100163 assertTimes (1, 1, 2, "tYEL not manually set to default correctly!");164165 value = 4’d9;166 reprogram = 0;167 #100168 assertTimes (1, 1, 2, "tYEL set when ~reprogram!");169170 value = 4’d0;171 reprogram = 1;172 #100173 // tYEL ==0 is patently dangerous , so it ’s forced to 1 internally174 assertTimes (1, 1, 1, "tYEL not set correctly!");175176177 // finally , test a useful reset of all the parameters178 reset = 1;179 #100180 assertTimes (6, 3, 2, "reset didn ’t set values properly!");181182183 $display("Passed test of TimeParameters ...");184 end185186 endmodule

5.12 TestTimer.v

37

Page 38: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

1 // establish time units for delays used in test module2 ‘timescale 1ns / 1ps34 /**5 * A small test module for Timer.6 */7 module TestTimer ();8 reg reset;9 reg [11:0] timeParameters;

10 reg [1:0] selector;11 reg startTimer;1213 wire expired;14 wire oneHzTmp;151617 reg clk;1819 Timer test(clk ,20 reset ,21 timeParameters , selector ,22 startTimer ,23 expired );24252627 /**28 * Helper task to check that clkCycleCount has the desired value.29 *30 * @param clkCycleCount31 * the expected value of clkCycleCount32 * @param msg33 * a string to be displayed if the count is not what it should be; must34 * be 70 or fewer characters35 */36 task assertCycleCount; // ( clkCycleCount )37 input [24:0] clkCycleCount;3839 if (test.clkCycleCount !== clkCycleCount)40 begin41 $display("error: unexpected cycle count");42 $display(" expected: %d", clkCycleCount );43 $display(" actual: %d", test.clkCycleCount );44 $stop ();45 end46 endtask474849 /**50 * Helper task to check that expired has the desired value.51 *52 * @param expired53 * the expected value of expired54 * @param msg55 * a string to be displayed if expired is not what it should be; must56 * be 70 or fewer characters57 */58 task assertExpired; // (expired)59 input exp;6061 if (test.expired !== exp)62 begin63 $display("error: expired has unexpected value");64 $display(" expected: %d", exp);65 $display(" actual: %d", test.expired );66 $stop ();67 end68 endtask

38

Page 39: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

697071 initial begin72 clk = 0;73 forever #0.5 clk = ~clk;74 end7576 initial77 begin78 $display("Starting test of Timer ...");7980 reset = 1;81 timeParameters = {4’b0001 , 4’b0011 , 4’b0010 };82 selector = 2’b0;83 startTimer = 0;84 #18586 assertCycleCount (25’d0);87 assertExpired (0);8889 reset = 0;90 startTimer = 1;9192 #193 assertCycleCount (25’d0);94 assertExpired (0);9596 startTimer = 0;97 #198 assertCycleCount (25’d1);99 assertExpired (0);

100101 #1102 assertCycleCount (25’d2);103 assertExpired (0);104105 #26 _999_995106 assertCycleCount (25’ d26_999_997 );107 assertExpired (0);108109 #1110 assertCycleCount (25’ d26_999_998 );111 assertExpired (0);112113 #1114 assertCycleCount (25’ d26_999_999 );115 assertExpired (0);116117 #1118 assertCycleCount (25’d0);119 assertExpired (1); // note: expires cycle *after* reaching max count120121 #1122 assertCycleCount (25’d1);123 assertExpired (0);124125 #1126 assertCycleCount (25’d2);127 assertExpired (0);128129 $display("Passed test of Timer ...");130 end131132 endmodule

5.13 TestTrafficController.v

39

Page 40: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

1 // establish time units for delays used in test module2 ‘timescale 1 ns / 100 ps34 /**5 * A small test module for TrafficController .6 */7 module TestTrafficController ();8 integer i;9

10 reg clk , reset , trafficSensor , walkRequest , reprogram;11 reg [1:0] timeSelector;12 reg [3:0] value;1314 wire redMain , yellowMain , greenMain;15 wire redSide , yellowSide , greenSide;16 wire walkLight;17 wire [2:0] STATE;18 wire oneHzTmp;19 TrafficController test(clk , reset , trafficSensor , walkRequest , reprogram ,20 timeSelector , value ,21 redMain , yellowMain , greenMain ,22 redSide , yellowSide , greenSide ,23 walkLight , STATE);2425 // clk has 50% duty cycle , 1ns period (1 time unit per cycle)26 initial begin27 clk = 0;28 forever #0.5 clk = ~clk;29 end303132 initial33 begin34 $display("Starting test of TrafficController ...");3536 reset = 1’b1;37 trafficSensor = 1’b0;38 walkRequest = 1’b0;39 reprogram = 1’b0;40 timeSelector = 2’b0;41 value = 4’b1;42 #143 reset = 0;44 #14546 for (i = 0; i < 55 _000_000; i = i + 1)47 begin48 #149 $display("clk: %d, cycle: %d, expired: %d, startTimer: %d",50 clk ,51 test.timer.clkCycleCount ,52 test.timer.expired ,53 test.fsm.startTimer );54 end5556 $display("Passed test of TrafficController ...");57 $finish;58 end59 endmodule

5.14 TestWalkRegister.v

1 // establish time units for delays used in test module2 ‘timescale 1 ns / 100 ps34 /**5 * A small test module for WalkRegister .

40

Page 41: A Traffic Controller for a Two-Street Intersectionweb.mit.edu/jwalden/www/traffic-controller.pdf · A Traffic Controller for a Two-Street Intersection Jeff Walden– 6.111 8.10.06

6 */7 module TestWalkRegister ();8 reg clk , walkPush , reset;9 wire pendingWalk;

1011 // make an instance of WalkRegister12 WalkRegister test(clk , walkPush , reset , pendingWalk );1314 // clk has 50% duty cycle , 100 ns period15 initial begin16 clk = 0;17 forever #50 clk = ~clk;18 end1920 initial begin21 $display("Starting test of WalkRegister ...");2223 // clear the counter24 reset = 1;25 #10026 if (pendingWalk !== 0) begin27 $display("reset should trigger pendingWalk == 0");28 $stop ();29 end3031 // does it stay clear when button pushed?32 walkPush = 1;33 #10034 if (pendingWalk !== 0) begin35 $display("reset == 1 overrides pendingWalk == 1");36 $stop ();37 end3839 // un -reset , push button40 reset = 0;41 walkPush = 1;42 #10043 if (pendingWalk !== 1) begin44 $display("walkPush but no pendingWalk!");45 $stop ();46 end4748 // does it stay 1?49 walkPush = 0;50 #10051 if (pendingWalk !== 1) begin52 $display("walkPush shouldn ’t need to stay 1 for pendingWalk == 1");53 $stop ();54 end5556 // clear it57 reset = 1;58 #10059 if (pendingWalk !== 0) begin60 $display("reset but pendingWalk == 1");61 $stop ();62 end6364 $display("Passed test of WalkRegister ...");65 end6667 endmodule

41