Goal: implement simple circuits in Verilog and run ModelSim from command line and within ISE; download and run a sample circuit on the labkit.
Useful links
Exercise 1: Writing Verilog code
In this exercise you'll design a Verilog module that implements a 74LS163. Here are the steps:
Type: tcsh This will ensure that the shell program you're running is cshell, which we know to have working scripts for.
Type: add 6.111 This will add the 6.111 locker, allowing you to access various files important for 6.111.
Type: source /mit/6.111/tools.tcsh This will set up the 6.111 tools (Modelsim, Xilinx ISE and Impact).
To run Modelsim type: vsim & (the '&' allows you to keep typing in the terminal) To run Xilinx ISE type: ise & To run Xilinx Impact type: impact &
You can setup your environment permanently and avoid adding the locker and set up command each time you login by customizing your configuration file. First determine your shell by
Type: ps Look at what is listed under the CMD column. It should be either tcsh or bash (the name of your shell program). Most accounts created after 2009 use bash.
If you have tcsh, add the following to ~/.cshrc.mine
add 6.111 source /mit/6.111/tools.tcshIf you have bash, add the the following to ~/.bashrc.mine
add 6.111 alias ise="tcsh -c 'source /mit/6.111/tools.tcsh;ise'" alias vsim="tcsh -c 'source /mit/6.111/tools.tcsh;vsim'" alias impact="tcsh -c 'source /mit/6.111/tools.tcsh;impact'"
The steps below describe how to use our Verilog simulator Modelsim as a standalone application. One can also run the simulator from the Xilinx ISE toolkit -- see the labkit documentation Simulating with Modelsim for details on how to do this. Feel free to use either approach for this part of the lab.
# Starting test of LS163... # clear was asserted low, but counter didn't clear # out = xxxx, expected 0000 # Break at lab2_1.v line 48
These messages were generated by code inside the test module as it runs
through various tests of the LS163 module. The LS163 module supplied in
lab2_1.v is empty which is why the test failed. Your job is to fill in the
body for the LS163 module, implementing the correct functionality. Refer
to the 74LS163 datasheet to see what functionality your code needs to
implement.
With Verilog, the description for a counter is simply
counter <= counter + 1; // on each clock, add 1To implent the LS163 with outputs qd, qc, qb, qa use the concatenation operator {}. Verilog will handle arithemtic operations correctly, eg: {qd,qc,qb,qa} + 1;
You can use the editor of your choice to edit lab2_1.v appropriately. Modelsim has a simple built-in editor which should be displaying lab2_1.v after you completed step 8. To use the built-in editor, click on the the tool bar option "Source" and uncheck the "Read Only" line. As you edit lab2_1.v, repeat steps 6 through 8 above to test your code. When you're successful you'll see
# Starting test of LS163... # Finished test of LS163...
Exercise 1 (b): Modelsim - Behavior simulation, waveform display
In this exercise you'll use the ls163 code and verify operation through behavior simulation with Modelsim within ISE.
Variables in Verilog that are set inside an "always" block (qa,qb,qc,qd) block must be declared as "reg" so insert "reg" after "output" for qa,qb,qc,qd.
Click on the test bench "ls163_tb". To create a 10ns clock, find the line "initial begin" in your test bench and insert
always #5 clk = !clk; // change state every 5nsbefore the line "initial begin". To initialize the counter to the value nine and begin counting, copy and paste the following lines your test bench "ls163_tb" after the line "// Add stimulus here"
////////////////////////////////////////////// // clear = 1; load = 0; // note load is active low a = 1; // now load 8'b1001 to counter b = 0; c = 0; d = 1; ent = 1; // enp = ent = 1 to count enp = 1; #20; // wait for 20ns load = 1; // /////////////////////////////////////////////
Save the changes.
Double click on "Simulate Behavior Model". Modelsim and a Waveform window will pop up. With the mouse in the waveform window right click "Zoom Full" to view the full simulation. Simulating with Modelsim contains examples of complex test benches. You should see the counter cycle from 9-15 with RCO high on a count of 15.
Exercise 2: Compiling and running Verilog on the labkit
In this exercise you'll design a Verilog module that reads a 4-bit value from labkit's switches and displays the appropriate hex digit on a 7-segment display.
The labkit module (defined in labkit.v) has port declarations for all the labkit peripherals as well as supplying default values for all the output ports. This is the top-level module for all labkit projects -- you should make a copy of it using a meaningful file name (eg, lab2_2.v) and modify the copy to implement the circuitry for your project. labkit.ucf (which you'll never need to modify) specifies which FPGA pin is connected to which named port in labkit.v.
Compute the appropriate value for each of segment control signals and drive them onto the appropriate FPGA output pins (I used user1[7:0]). (There are two rows of pins. Be sure to use the signal pins and not the grounds.) Note that you'll have to modify or comment-out the existing line in the code that sets a default value for the output pins you're using.
Synthesize and implement your design. Generate a programming file and configure the FPGA. When your circuit is working, you should be able to display 0-f on the 7-segment display using the switches.
Unless you following the instructions exactly, you synthesis will fail - labkit.ucf file includes constraints for all of the input and output ports defined in labkit.v. Most designs, however, will not use all of these signals, in which case the synthesis engine will optimize the unused signals out of the design. The location constraints in labkit.ucf for these unused signals will then generate errors. It is therefore necessary to tell ISE not to generate an error if it encounters a pin constraint for a (now) nonexistent signal. To do this, right-click on the "Implement Design" item in the process pane, and select "Properties...". Check the box to "allow unmatched LOC constraints" in the "Translate Properties" form.
Add Verilog to your module by replacing 4 slide switches with the output of a 4 bit counter. Increment the count on every rising edge of button_enter.
////////////////////////////////////////////// // always @(posedge button_enter) counter<=counter+1; // // using the edge of an external input as a // clock is poor design practice! /////////////////////////////////////////////Because of switch bounce, the counter may increment by more than one. Switch bounce typically disappears after 10-20 ms. One approach to debouncing is to sample the input. The input is considered valid only if the value is the same for some period of time. Add Verilog to debounce the switch input so that each press of button_enter increments the count by one. For debouncer, a signal is considered to be clean if the value remains the same for 10msec. With a 27mhz clock, that's 270,000-1 clock cycles. Step 1: At each clock pulse, store the new input into a reg Step 2: if the new input is the same as the previous input, increment a counter. If not it must be switch bounce so set the counter to zero. When the counter reaches 270,000-1, you have a debounced input. Here's a skelton of the debounce Verilog:
////////////////////////////////////////////// // module debounce( input clk, // check the name of your clock input reset, // system reset input bouncey_input, output reg clean_data ); reg [18:0] count; // is 19 bits enough? reg old; always @(posedge clk) begin ... your Verilog end endmodule // /////////////////////////////////////////////When your circuit is working, ask a staff member to check you off. (1.1 point) For checkoff be prepared to show your circuit in operation, incrementing the count with each button_enter press.