Link to repo: fpga-tutorial
We'll be working in the verilog
directory.
You will need the following:
- An editor that understands Verilog. Atom or Sublime Text should be fine.
- Icarus Verilog. Your system should have it
packaged:
apt install iverilog
brew install icarus-verilog
- ...
- Optionally GTKWave. This should also be available from your system.
To run adder_tb.v
, use:
make run V=adder_tb.v
To run adder.v
and view the results in GTKWave, use:
make sim V=adder_tb.v
Let's say we have not
, and
, or
, xor
, etc. Try to draw a half-adder. A
half-adder is a component that adds 2 bits (x
, y
), and outputs a sum (s
)
and a carry bit (c_out
):
x y s c_out
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1
Now, use half-adders to construct an adder. An adder adds two bits and a carry-in (c_in
):
x y c_in s c_out
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1
Finally, use the adders to construct a 4-bit adder:
x y s c
0000 0000 0000 0
0000 0001 0001 0
...
1001 0011 1100 0
...
1111 0001 0000 1
...
1111 1111 1110 1
Now, implement the same (half-adder, adder, and 4-bit adder) in adder.v
,
using Verilog.
You can run the test-bench (adder_tb.v
) and print values to test the adder.
Later, check that you can do the same using an arithmetic expression: assign s = x + y
.
What does it do? Draw a table, it will help with the next exercise.
Optionally: implement and test in Verilog.
Here is a D flip-flop:
What does it do?
- Hint: Analyze what happens when Clock = 0, then when Clock changes to 1, then when clock stays at 1 and Data changes.
- Spoilers:
Implement it and test it in Verilog using primitive components (nand
gates).
Now implement the same using a reg
and always @(posedge clock)
.
Implement a counter:
module counter(input wire clk,
input wire en,
input wire rst,
output reg [3:0] count);
You can use the provided counter.v
and counter_tb.v
.
The counter should increase on a positive clock edge whenever en
(enable) is
set, and reset to 0 whenever rst
(reset) is set:
Given a clock signal, output a clock signal that is 4 times slower.
module clock_divider(input wire clk_in,
output wire clk_out);
In other words, we should get:
clk_in: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ....
clk_out: 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 ....
Can you do the same, but 1024 times slower? (1024 = 2 to the 10th power, or
1 << 10
).
module traffic(input wire clk,
input wire go,
output wire red,
output wire yellow,
output wire green);
You can use the provided traffic.v
and traffic_tb.v
.
- Initially, the
red
light should be lit (1). - When
go
is set to 1, you should light upred
andyellow
for 3 cycles, then switch togreen
. - When
go
is set back to 0, you should lightyellow
for 3 cycles, then switch tored
.
Write a module that receives an 8-bit value and converts it to single bits.
module serial(input wire clk,
input wire in,
input wire [7:0] data,
output wire out);
- Normally,
out
should be 0. - The user should raise
in
to 1 for a single cycle, and setdata
to a desired value in the same cycle. - Then, during the following 8 cycles,
out
should contain consecutive bits ofdata
(highest to lowest). - After that,
out
should go back to 0.
For instance, if we set in = 1
and data = 8'b01101001
for a single cycle;
out
should be set to: 0, 1, 1, 0, 1, 0, 0, 1. Then it should return to 0
until in
is raised again.
Implement a 256-byte memory module with read and write ports.
module memory(input wire clk,
input wire ren,
input wire [7:0] raddr,
output reg [7:0] rdata,
input wire wen,
input wire [7:0] waddr,
input wire [7:0] wdata);
- When
ren
(read enable) is set, in the next cycle setrdata
to the byte atraddr
address. - When
wen
(write enable) is set, in the next cycle set the byte atwaddr
address towdata
. - Both operations (read and write) can happen in the same cycle.
Write a test bench. What will be the result of reading uninitialized memory? How to initialize the memory to 0?
Hint: You can use a $display
statement to print debug messages while the
module is working (for instance, "Storing byte XX at address YY"
).
- Verilog cheatsheet (PDF)
- HDLBits - online, interactive Verilog exercises
- Verilog Beginner's Tutorial by ZipCPU author