Verilog Introduction: Synopsis

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Verilog 

Introduction 
Synopsis 
This  lab  introduces  you  to  Verilog.    The  lab  consists  of  four  "mini"‐projects  that  will  introduce  you  to 
Verilog syntax, operations, and grammar.  Your TA will supplement this handout with a Verilog tutorial.  
Your TA will also introduce you to ModelSim to increase your coding efficiency and enhance your ability 
to debug. 

Each section presents a separate (independent) task.  You will also find a few questions at the end of each 
task.  You should write (or type) your answers to these and turn them in with your lab. 

Mini‐“Projects” 
Arbitrary clock divider 
Objective 
The Nexys3 FPGA uses a 100MHz clock.  You learned in the detour and number‐lock labs how to use a 
clock divider to produce a slower clock by using a clock divider.  But our clock divider produces only clocks 
with frequencies of 100MHz divided by powers of 2 (50MHz, 25MHz, 12.5MHz, etc.).  In this project you 
will build a circuit to produce a clock with a specific desired frequency.  This will be useful to many term 
projects. 

Introduction 
Remember  that  you  can  use  a  clock  divider  with  the  Nexys3  FPGA  to  generate  clocks  with  slower 
frequency.  You do this by using a large counter to output DIV_CLK[31:0].  Each successive bit in the 
counter divides the frequency by 2 (doubling the period).  So, 
BOARD_CLK = 100MHz
DIV_CLK[0] = 50MHz
DIV_CLK[1] = 25MHz
DIV_CLK[2] = 12.5MHz
...
DIV_CLK[25] = 1.49Hz
...
 

But what if you need a clock with 60Hz?  Here we need an alternate method. 

Notice that a 60Hz clock "toggles" 120 times / second since each clock has an "up"‐part and a "down"‐
part.  So if a signal toggles a register at 120Hz the register will output a 60Hz clock.  We now have 2 distinct 
(but easier) problems to solve: 

1. create a signal (let’s call it count PULSE) with 120 pulses per second 
2. create a toggle register and input PULSE 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

The  procedure  and  code  will  step  you  through  the  process  of  creating  a  hierarchical  design  that 
implements  these  functions.    NOTE:  you  would  not  normally  break  Verilog  modules  into  such  atomic 
functions because it might reduce the tools ability to optimize your code. 

   

Procedure 
1. Open the ee201_pulse_atN module in ModelSim. 
2. Consider a 4‐bit counter.  Remember that the CEO output is high when all four output bits are 1 
(i.e. 1111 = F).  So if you input a CLK with 100Mhz to the counter the CEO pulses at 100MHz / 
16 = 6.25 million times per second.  Each pulse is exactly 1‐clock wide since on the next clock the 
4‐bit counter rolls over to 0 (1111 -> 0000) and so CEO return to 0. 
 
So a 4‐bit FF rolls over (starts at 0) every 2^4 = 16 clocks.  Now suppose you had a circuit that 
counted 0, 1, 2 …, 9, 0, 1 ... (counts to 10) with CEO = 1 when COUNT = 9.  Then CEO pulses every 
100MHz / 10 = 10MHz (pulse width = 1 clock).   
 
Follow this reasoning to complete (TODOs) the ee201_pulse_atN module.  This module takes 
an input N and produces a pulse after N clocks. 
3. Use the ee201_pulse_atN_tb to simulate your design.  Count the number of clocks between 
pulses (HINT: N has three different values during the simulation). 
4. Open the ee201_clk_60Hz module in ModelSim. 
5. Complete (TODOs) the module.  Several of the comments provide helpful hints. 
6. Use the ee201_clk_60Hz_tb to simulate your design. 
 

Questions 
1. Using the waveform what are the three different values of N in the ee201_pulse_atN_tb
simulation? 
a. The frequency of the clock is 100MHz.  What is the frequency of the pulses for each value 
of N?  
2. Print modules:  
a. ee201_pulse_atN.v 
b. ee201_clk_60Hz.v 
3. Print waveforms from simulations:  
a. ee201_pulse_atN_tb.v 
b. ee201_clk_60Hz_tb.v 

Weighted coin and die simulator 
Objective 
Randomness is hard to come‐by in digital circuits.  Verilog can generate pseudorandom numbers using 
$random().  But this code is NOT synthesizable.  So you cannot use $random() in circuits destined for 
the Nexys3.  This project shows how you can use an asynchronous input (not with the clock) ‐‐ a button 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

and a fast clock to produce ~almost~ uniform randomness.  You will then add some combinational logic 
to add "weighting" (like an unfair coin: 25% heads and 75% tails). 

Introduction 
Imagine a pendulum swinging back and forth.  Suppose you have a button that records the position of the 
pendulum each time you press it.  Suppose the pendulum is swinging back very slowly (1Hz).   If you are 
watching the pendulum you could hit the button so that it records the position in almost the same spot 
(not exactly, but close) ‐‐ remember its going very slow.  Notice that the same thing happens if you decide 
to  regularly  press  the  button  every  1  second  or  so  since  the  pendulum  is  swinging  at  about  the  same 
frequency. 

Now imagine the pendulum getting faster, 10Hz.  And faster, 1000Hz.  Now the pendulum is moving so 
fast that you cannot press the button at the same position even if you tried.  Even if you press the button 
as  fast  as  you  can  the  pendulum  will  make  several  swings  in  between  each  press.    The  upshot  is  that 
instead of producing a predictable pattern (like in 1Hz) you will get random positions across the swing. 

You can use a fast counter to produce a similar effect in digital logic.  Suppose you have a 2‐bit counter 
(0, 1, 2, 3, 0, 1 ...) connected to the fast 100MHz Nexys3 clock.  Every time you press the button it is equally 
likely that the counter is 0, or 1, or 2, or 3.  So we have produced a uniform 4‐option random variable (a 
4‐sided dice ‐‐ a tetrahedron, 1D4).  We can also simulate a coin‐flip by using a 1‐bit counter (0, 1, 0, 1) 
with 0 = heads and 1 = tails.  And if we want to simulate a 6‐sided die then we can use a 3‐bit counter and 
clear the counter every time it hits 5 so it rolls back to 0 ‐‐ 0, 1, 2, 3, 4, 5, 0, 1, ... 

Now let’s simulate a coin‐flip that was unfair ‐‐ weighted a little in our favor ‐‐ so H = 25% and T = 75% 
(instead of 50/50).  We can use a 2‐bit counter and "group" possibilities.  Remember that our 2‐bit counter 
(0, 1, 2, 3, 0 …) has 4 distinct values.  By grouping: 
if(COUNT=0)
OUTPUT = head
if(COUNT=1 OR COUNT=2 OR COUNT=3)
OUTPUT = tail
 

so OUTPUT=head only 1/4 of the time (25%) and OUTPUT=tail 3/4 of the time (75%). 

The procedure will step you through code that simulates rolling a fair coin and a fair die.  You then finish 
the project to cheat just a little by adding some unfairness to your coin flip. 

Procedure 
1. Open the ee201_roller module in ModelSim. 

Complete (TODOs) the module.   

2. Modify  ee201_roller  to  simulate  flipping  a  fair  coin.    Complete  the  TODO  in 
ee201_roller_tb  and simulate. 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

Repeat to simulate rolling a fair die. 

3. Uncomment (remove the /** and **/) the "Part 2" sections in the ee201_roller module to enable 
weighting. 

  Complete (TODOs) in this section.   

4. Simulate with ee201_roller (update the testbench as necessary).  Run the simulation for 
1000ns = 1us.  Record the tally statistics in the ModelSim (vsim) console.   

Run the simulation for 9000ns MORE (total: 10us).  Record the statistics in the ModelSim (vsim) 
console.   

Run  the  simulation  for  990ms  MORE  (total:  1s).    Record  the  statistics  in  the  ModelSim  (vsim) 
console.     

5. Open the top module (ee201_roller_top). 

  Complete (TODOs) the module.   

Create a new project in Xilinx with your Verilog files.  Use the same directory so the ModelSim 
and Xilinx projects share the same directory. 

  Configure your device type, set startup clock = JTAG clock, and generate a bitfile. 

Use Adept to load the bitfile onto your FPGA.  After you reset (BtnC) the device use BtnL to flip 
your unfair coin (20/80).  Press the button 20 times and record the number of heads and tails. 

 Questions 
1. How did the module output the unfair flip in Part II since it output the fair flip in "Part 1"? 
2. Compare the simulated fair coin flip to the instance on your FPGA. (COMPLETE) 
 

Synchronous vs. Asynchronous FF resets 
Objective 
The lab tries to show through simulation the difference between FFs with asynchronous and synchronous 
reset and also with or without a data‐enable. 

Introduction 
We have provided a project folder, where you can find a project file (.mpf), two Verilog source files (.v), 
two script files (.do), and this lab manual. You can invoke this project in ModelSim as follows. Make sure 
that the path of target .mpf file is correctly selected. 

File > Open > ff_reset_verilog.mpf 

The first source file (ff_reset_verilog.v) is the main design file, where different versions of Flip‐
flop outs (represented as Q_*) have been generated for different purposes. These Q_* can be found in 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

Table 1. The second source file (ff_reset_verilog_tb.v) is the testbench to test the design file. A 
typical testbench file usually generates clock signal, apply stimulus/input vectors, etc. 

Q_* How they are generated? 
Q_bad_r BAD coding results in treating the RESET as a Data enable 
Q_async_r FF with asynchronous reset 
Q_sync_r FF with synchronous reset 
Q_no_r FF with no reset at all 
Q_async_r_de FF with asynchronous reset with Data Enable 
Q_sync_r_de FF with synchronous reset with Data Enable 
Q_no_r_de FF with Data Enable but no reset at all 
 

Procedure 
1. Complete  TODOs  by  setting  a  default  Q  value  when  reset  in  ff_reset_verilog.v,  either 
using Notepad++ or ModelSim as editor. 
2. In ModelSim, compile the design file and testbench file and make sure your design has no syntax 
errors.  Errors will be displayed in the transcript window. 
3. Run  command:  do  ff_reset_verilog.do  in  the  transcript  window  in  ModelSim,  which 
invokes  another  .do  file.  These  two  scripts  simulate  your  design  for  600ns  and  display  the 
waveforms. 
 

Questions 
1. Answer questions in ff_reset_verilog.v and discuss with your TA. 
 

Divider RTL design in Verilog 
Objective 
This module will introduce you to RTL coding style for state machine and datapath coding.  It will also 
further your understanding of basic Verilog syntax (case, if-else, always, assign, etc.). 

Introduction 
A zip file is provided containing a ModelSim project, two source files and a test bench file. Please read the 
notes at the top of each file to get to know important aspects of the design to note. 
1. divider_combined_cu_dpu.v
2. divider_separate_cu_dpu.v
3. divider_tb_str.v

* ee201l_divider_lab.mpf > ModelSim project 

A short description of each of the above 3 files follows. 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

divider_combined_cu_dpu.v 
A Verilog module for a simple divider. It takes two 4‐bit inputs Xin and Yin (dividend and divisor) and 
produce 4‐bit Quotient and Remainder, and three state bits, Qi, Qc, and Qd, as outputs.  There are inputs 
that control the state machine as well (Start, Ack, Clk, Reset, and Done) 
module divider (Xin, Yin, Start, Ack, Clk, Reset, Done, Quotient,
Remainder, Qi, Qc, Qd)

Note  that  the  name  of  the  module  is  divider,  and  we’re  going  to  use  a  single  test  bench  to  test  two 
different divider designs divider_combined_cu_dpu.v and divider_separate_cu_dpu.v.  
Their functionalities are identical. 

There are three states – INITIAL, COMPUTE and DONE_S ‐ in the state machine and they are one‐hot 
coded as below. 
localparam
INITIAL = 3'b001,
COMPUTE = 3'b010,
DONE_S = 3'b100;
 

In this file, there is a single always block where you can locate NSL and SM for three states listed above.  

divider_separate_cu_dpu.v 
Another Verilog module for a simple divider. In this design, there are two separate always blocks, where 
one is for CU and the other is for DPU. There are some blank indicated as ‘TODO’ in this file, for students 
to complete. 

divider_tb_str.v 
A test bench file that performs three divider operations. These are 15 ÷ 7, 5 ÷ 8 and 11 ÷ 3. Run ModelSim 
simulation and see messages in the transcript panel for results of the above three operations. 

Procedure 
1. Read file divider_combined_cu_dpu.v and answer to exercise question 7‐a. 
2. Open  ee201l_divider_lab.mpf  and  type  do  divider.do  in  the  transcript  panel.  See 
messages in the transcript panel and check results of three divider operations. 
3. Type quit –sim to escape from simulation. 
4. Read file divider_separate_cu_dpu.v and fill‐in every TODO blank. 
5. In the same project ee201l_divider_lab, type do divider_exercise.do in the transcript panel. See 
messages  in  the  transcript  panel  and  compare  results  of  three  divider  operations  with  those 
obtained from 6‐b. 
6. Answer to question 7‐c. If necessary, change the line in divider_combined_cu_dpu.v and 
repeat procedure 6‐b again to see the difference (or they could be the same) 
 

Questions 
1. Complete a state machine of the divider module based on divider_combined_cu_dpu.v. 


 
EE201L ‐ Introduction to Digital Circuits    Verilog Introduction 
 

RESET

INITIAL  COMPUTE  DONE_S 


X <= 4’bXXXX; Start    
Y <= 4’bXXXX;
Z <= 4’bXXXX;    
 
   

2. Fill‐in every blank named TODO in divider_separate_cu_dpu.v. 
3. In divider_combined_cu_dpu.v, what will happen if line 73 
if (!(X < Y))

is changed to 

if (X > Y)? 

Can we still obtain correct results from the modified divider design? How about three test cases 
in our test bench? 


 

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy