$25
Problem 1 (15 pts)
In this problem and the next we are going to do some fairly straightforward sequential design. You do not need to simulate your results and/or turn in console transcripts. You should, however structure your code and use meaningful variable names. Since you are not simulating your design we will grade your code, so correct functioning, neatness and readability count. You will write this code from scratch – no starter files. I am including these problems to help you prepare for the final exam – they are representative of the type of problems you may see on the exam.
The term shift register is applied to circuits where flip-flops are wired in series. That is, the output of one flip-flop is wired to the input of the next. All of the flip-flops load new values on the clock edge. Since all of the flip-flops are edge triggered and all are triggered on the same clock edge, the transfer of these values between flip-flops happens in unison. One common type of shift register is called a serialin, parallel-out shift registers.
Write a SystemVerilog model for the following schematic: You can assume that all of the flip-flops are clocked on the positive edge of CLK and that when SHIFT = 1’b0 the register loads its old value. When SHIFT = 1’b1 the register shifts right (i.e. each flip-flop loads it left neighbor’s value). CLR is a synchronous reset (Q -> 0) for all of the flip-flops.
Problem 2 (15 pts)
Understanding how to design and implement Finite State Machines is a must-have skill to be a successful Computer Engineer. While we normally teach FSM design in digital logic courses, FSM’s play just as big a role in many software applications, too.
In this problem we are going to implement a FSM-based controller for a car wash. The car wash supports two kinds of washes. The inexpensive wash (cost = 1 token) simply sprays the vehicle for a set period of time. The deluxe car wash (cost = 2 tokens) consists of three steps: (1) rinse the vehicle with water, (2) apply soap, and (3) rinse the vehicle again. So, how does the FSM determine which car wash the customer wants? That’s what the START signal is for. For an inexpensive car wash the customer inserts a single token and presses the START button. For a deluxe car wash the customer inserts a second token without pressing the START button. A state transition diagram for this controller is shown below:
Design and implement this FSM (a Moore machine since the outputs are only dependent on the current state) in SystemVerilog using the 3 always-block method. Like the previous problem, you do not need to simulate the design but you do need to write nicely structured, readable code. You may start with the signature on the next page:
module carwash_fsm (
input logic
clk, CLR,
// clock and reset signal. CLR is asserted high
// to reset the FSM
input logic
TOKEN,
// customer inserted a token. Asserted high
input logic
START,
// customer pressed the START button. Asserted high
input logic
T1DONE,
// spray time has expired. Asserted high
input logic
T2DONE,
// rinse time (after soap) has expired. Asserted
// high
output logic
CLRT1,
// clear the spray timer. Assert high
output logic
CLRT2,
// clear the rinse timer. Assert high
output logic
SOAP,
// apply soap. Assert high
output logic
);
SPRAY
// turn on the spray. Assert high
Problem 2 (70 pts)
This problem consists of completing the design, implementation, and simulation of a single
SystemVerilog module that provides an interface to a Digilent PmodSSD two-digit 7-segment display. (http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,401,481&Prod=PMOD-SSD). Yes, we are using SystemVerilog to implement hardware that controls other hardware, in this case a peripheral device.
You have been provided with the PmodSSD datasheet and schematic, a working emulation of the PmodSSD, a working testbench and a parameterized clock divider. Your task is to implement an interface to the peripheral that has as its input, 2 character code registers (one for each digit), a clock and a reset and provides outputs to drive the control signals on the PmodSSD. Success will be demonstrated by providing a waveform and transcript of your simulation.
Functional Specification
Consider the design of an interface to the Digilent PmodSSD. As you will see from the datasheet, its connections are 7 anode pins (called AA-AG in the datasheet) shared between the two digits, a digitenable signal (called C in the datasheet) that is switched at a frequency of at least 50Hz to select first one and then the other digit and VDD and GND. Your interface will need to generate the C and AA-AG signals for the two multiplexed digits, first converting the character codes provided as inputs into the 7 segment values that will control each of the LED segments representing the character. The datasheet provides a good explanation of how to use the digit-enable signal to drive the two digits so no further detail will be provided her
Task list
STEP 1: Download the Homework #3 release package
Download and unzip ecw351sp20_hw3_release.zip from D2L. This .zip file contains this document and others, as well as a PmodSSD emulator and testbench. A waveform configuration file (wave.do) for ModelSim or QuestaSim is also included. This file should work for your design as long as the signal names match.
STEP 2: Study/Understand the datasheet, schematic and the HDL provided
You will note that this problem write-up is briefer and provides less detail than the previous write-ups.
While this may make you feel uncomfortable, the information you need to complete this project is in the HDL code and the documentation that has been provided. As fledgling SystemVerilog designers (you have to admit, you’ve come a long way since the start of the term) you should be at the point where you can focus less on syntax and tools and more on creating an original design – that’s the main objective for this assignment.
STEP 3: Implement the character code to 7-segment decoder
In a display subsystem such as this one, the data to be displayed is presented to the interface using a character code. That character code needs to be translated into the individual signals that are driven to each of the segments of a digit (the AA..AG signals on the PmodSSD). For this problem we will use the following translation table:
Character Code
Displays
0 - 9
Characters 0 to 9
10 – 15
Upper case characters A to F
16 – 22
Single segments a to g
23
Space (Blank)
24*
Upper case character H
25*
Upper case character L
26*
Upper case character R
27*
Lower case character L (l)
28*
Lower case character R ( r )
29 – 31
Space (blank)
* These special characters are easy to produce on the 7-segment display because they map well to the segments. The exceptions are the Upper Case R which looks just like an upper case A and the lower case L which looks like a 1 (one). The good news is that you can use the same 7-segment patterns for both of them. The bad news is that your user can’t tell them apart…everything is a tradeoff *sigh*
There are several ways to implement this functionality. For example, you could place the decoder in a separate module or you could include a case statement in your interface. For this problem please implement the decoder using a SystemVerilog function in your pmodSSD_Interface code. Functions were discussed in class and there is an example of a similar function in the testbench. A suitable translation table is provided with the release.
STEP 4: Implement the PmodSSD Interface
The purpose of the PmodSSD interface is three-fold:
First, the digit to be displayed needs to be translated from a character code to the 7-segment anode signals. Include the function you wrote in Step 3 in this module to perform the conversion. The 7 outputs from the conversion function are routed to the LED segments (abcdefg) in a display digit. For the PmodSSD display, an LED segment is lit by driving a logic 1 (1’b1) on the corresponding anode line. So, producing, for example the digit “5” on the display, the 7 anodes for that digit would be driven to 7'b1011011 (segments A, C, D, F, G) lit.
Second, the cathode signal (digit-enable) must be generated. This can be a 50% duty-cycle pulse of any frequency greater than 50 Hz. You can instantiate the clock divider module provided in the release to generate this signal. Assume that the input clock frequency is 100 MHz. The clock divider module generates a one clock pulse when the counter reaches its top count. This pulse can be converted to a 50% duty cycle signal with the following code:
// square up the clock to drive the digit enable
// This will give you a 50% duty cycle clock at 1/2 the frequency always_ff @(posedge clk) begin: digit_enable
if (reset) tick_60Hz <= 1'b0;
else if (tick_120Hz) // 2x the frequency for 50% on / 50% off
tick_60Hz <= ~tick_60Hz; else
tick_60Hz <= tick_60Hz; end: digit_enable
Third, you must multiplex the 7-segments from each digit onto the shared anode signals. This can be done with a 2:1 multiplexer. The select signal for this multiplexer is the cathode (digit-enable) signal produced from the clock divider.
You can use the following module definition to remain compatible with the provided test bench.
module pmodSSD_Interface
#(
parameter SIMULATE = 1 // set to 1 for this project, else it will take
// 100’s of thousand cycles of simulation time
)
(
// for each digit change.
input logic
clk, reset, // clock and reset signals
input logic[4:0]
digit1, digit0, // digit character codes
output logic
SSD_AG, SSD_AF, // Anode segment drivers
SSD_AE, SSD_AD,
SSD_AC, SSD_AB, SSD_AA,
output logic
);
SSD_C // Common cathode "digit enable"
STEP 5: Integrate your module with the PmodSSD emulator and testbench
The testbench for this problem instantiates and connects your PmodSSD_Interface module to the
PmodSSD emulator (pmodSSD_emu.v) provided in the release. The emulator was derived from the
PmodSSD schematic and models the PmodSSD pretty well. You should have studied this code already (Step 2) but it will greatly help your debug effort if you take the time to understand the code in the module. Of particular note is that besides de-multiplexing the shared anode signals, the output includes its own translation table (written as a SystemVerilog function) that converts your 7-segment output into ASCII characters that can be displayed by the simulator. In effect, the emulator dsply_digits port from the emulator output looks like a 2 digit display.
STEP 6: Test your design with the provided test bench
The testbench (hw3_prob3_tb.v) runs through all 32 character codes, driving digit0 with the character code and digit1 with its inverse. This serves two purposes. First, your 7-segment translation function is fully tested and second, by driving one digit as the inverse of the other the testbench also tests your multiplexing function.
The /sim directory in the project release provides a waveform configuration file (wave.do) that should prove useful in debugging your design and submitting your results. The wave.do file makes use of the ability for QuestaSim and ModelSim to create new display variables (combinations of existing variables) and display waveform values in Radix ASCII.
References
[1] Digilent PmodSSD™ Peripheral Module Board Reference Manual
[2] Digilent Seven Segment Display Module Schematic
[3] Wikipedia articles on 7-segment displays