A bit vector can be declared signed
in
Verilog, so it is interpreted as an integer in 2’s Complement
Format. The table below shows all 3-bit binary vectors and the
corresponding 2’s complement interpretation:
Binary (2’s Comp) | Decimal | Binary (2’s Comp) | Decimal |
---|---|---|---|
000 | 0 | 111 | -1 |
001 | 1 | 110 | -2 |
010 | 2 | 101 | -3 |
011 | 3 | 100 | NA |
The value 100
is
Not Allowed (NA).
The syntax for declaring a signed
3-bit
integer a
is:
reg signed [2:0] a;
In 2’s Complement, a negative number -N
is obtained
from a positive number N
by two steps:
N
~N
using
normal addition, discarding the final carryIn Verilog syntax, these steps are expressed as ~N+1
or just -N
.
Complete the negative values in the table below.
Pos Dec | Pos Bin N |
Inv Bin ~N |
Neg Bin | Neg Dec |
---|---|---|---|---|
0 | 0000 | 1111 | 0000 | -0 |
+1 | 0001 | 1110 | 1111 | -1 |
+2 | 0010 | 1101 | 1110 | -2 |
+3 | 0011 | -3 | ||
+4 | 0100 | -4 | ||
+5 | 0101 | -5 | ||
+6 | 0110 | -6 | ||
+7 | 0111 | -7 |
Complete the binary addition table below. For each entry, write the binary result and, in parentheses, the decimal interpretation. Do the addition using binary arithmetic, and indicate overflow cases with an exclamation point (!).
101 (-3) | 110 (-2) | 111 (-1) | 000 (0) | 001 (1) | 010 (2) | 011 (3) | |
---|---|---|---|---|---|---|---|
101 (-3) | 010 (2)! | ||||||
110 (-2) | 011 (3)! | ||||||
111 (-1) | 100 (NA)! | ||||||
000 (0) | 101 (-3) | ||||||
001 (1) | 110 (-2) | ||||||
010 (2) | 111 (-1) | ||||||
011 (3) | 000 (1) |
Study the results from the 3-bit addition table. Is there an efficient way to detect overflow cases? Give a precise logic solution that detects all overflow events.
Sometimes we need to do operations on vectors of different bit width. Consider the snippet:
reg [2:0] a;
reg [3:0] b;
always @(a) begin
= a;
b end
This case is implemented in src/testbench.v
.
Open the file and study its contents. Run make
to perform the simulation. In the
output, notice that a
is copied
into b
as a positive
number. For example, a=101
yields b=0101
.
But what if a
is a
signed value? In that case a=101
corresponds to a decimal value of -3. Try modifying the declaration of
a
:
reg signed [2:0] a;
reg [3:0] b;
always @(a) begin
= a;
b end
With this change, when a=101
(-3), b
is sign
extended to be the same width as ‘b’, resulting in 1101
(-3).
This creates a bug potential since b
is not signed
, so its
value will be interpreted as +13.
Consider this modification:
reg signed [2:0] a;
reg [3:0] b;
reg [4:0] c;
always @(a) begin
= a;
b = b;
c end
In this chain of assignments, when a=101
,
it is sign-extended so that b=1101
,
but since b
is unsigned it is
zero extended to 01101
,
resulting in c=01101
(+13).
To avoid this bug, the best practice is to declare all vectors as signed if they could receive signed assignments.
signed
assignmentsModify src/testbench.v
by adding the signed
keyword
to vectors b
and c
. Repeat the simulation and verify
that the assignments are correctly sign-extended.
Modify your up/down counter so that it uses signed
operations. Copy your module and testbench code into src
. Also copy your build.tcl
and XDC files into your
working directory. Add them to your repository using git add
. Edit them to support signed
operation and detect signed overflow.
Your testbench should cover all overflow cases and log results in
test_results.txt
. Verify your
signed counter in simulation, then implement it on the Basys3 board and
demonstrate the following cases:
a=53
,
b=13
,
press rst
then up
until q
stops changinga=-17
,
b=37
,
press rst
then dn
until q
stops changinga=29
,
b=-17
,
press rst
then up
until q
stops changinga=-47
,
b=-43
,
press rst
then dn
until q
stops changingPhotograph the results and save the photos as case1
, case2
, etc with an appropriate
graphics extension. Then turn in your results using git
:
git add *.txt *.bit *.rpt src/*.v *.xdc *.tcl case*
git commit . -m "Complete"
git push origin main
Indicate on Canvas that your work is done.