Verilog supports several operations that work bit-by-bit across a
pair of vectors. Given two vectors a and b with the same bit width, we
have these operations:
| Operator | Operation |
|---|---|
a&b |
Bitwise AND |
a|b |
Bitwise OR |
a^b |
Bitwise XOR |
~(a&b) |
Bitwise NAND |
~(a|b) |
Bitwise NOR |
~(a^b) |
Bitwise XNOR |
A first example is given in src/testbench.v.
Open the file and study its contents. Run make to simulate the demo cases. The
first few lines look like this:
clk: 0 a: 00000000 b: 00000000 a&b: 00000000 a|b: 00000000 a^b: 00000000
clk: 1 a: 00100100 b: 10000001 a&b: 00000000 a|b: 10100101 a^b: 10100101
clk: 2 a: 00001001 b: 01100011 a&b: 00000001 a|b: 01101011 a^b: 01101010
Every bitwise operation returns a vector. For the last line, we have
a=00001001
and b=01100011,
and they share a non-zero value only in the last bit position. Therefore
the bitwise results are
a&b={0&0,0&1,0&1,0&0,1&0,0&0,0&1,1&1}=00000001.a|b={0|0,0|1,0|1,0|0,1|0,0|0,0|1,1|1}=01101011.a^b={0^0,0^1,0^1,0^0,1^0,0^0,0^1,1^1}=01101010.As an exercise, predict the results for NAND, NOR,
and XNOR operations. Modify testbench.v to test these operations,
and run the simulation to verify your calculations.
Create file named src/bitwise_operations.v
and declare a module named bitwise_operations. The module should
have these I/O ports:
clka and b with seven bits
eachop (short for
“operation”) with two bitsreg q with seven
bitsIn the module definition, make a clocked always
block:
always @(posedge clk) begin
//...your code here...//
endIn the always block, use if/else
statements to implement these cases:
op==0:
Bitwise AND q <= a&bop==1:
Bitwise OR q <= a|bop==2:
Bitwise XOR q <= a^bop==3:
Bitwise NOR q <=~(a|b)Next, in testbench.v, place
an instance of the bitwise_operations module. Modify the
testbench as follows:
reg named
op, initialized as 0.reg signals
a and b, initialized as 0.wire signal
qalways block
cycling through all values of op: 00,01,11,10,00,… and repeat$write and
$fwrite
lines to report the clock number, a, b, op and q. Optionally: use
if/else
conditions to report the operation name (“AND”, “OR”, etc) instead of
the numerical value of op.When finished, run make to
simulate your module. Carefully inspect the output and verify that the
correct operations are performed for each case.
Now edit build.tcl and change
the following:
read_xdc line: change to
bitwise_operations.xdcsynth_design line: change
top_module to bitwise_operationswrite_bitstream line: change
to bitwise_operations.bitNext open bitwise_operations.xdc. You will see a
lot of commented lines copied from Basys3_Master.xdc. First, note the
clk lines:
## Clock signal
#set_property PACKAGE_PIN W5 [get_ports clk]
#set_property IOSTANDARD LVCMOS33 [get_ports clk]
#create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]Since your design uses a clock, uncomment the lines
that reference the clk port and
start with set_property or create_clock. These properties are
necessary for the following:
PACKAGE_PIN to indicate
which FPGA pin is connected to the Basys3 clock signalIOSTANDARD to LVCMOS33, 3.3V CMOS-compatible logic
signals. Since the FPGA chip can support several different voltages and
signal configurations, it needs to be told which standard is used on the
Basys3 board.clock, which is critical for proper
routing and timing analysis.In the Basys3 XDC template, the first line pertaining to a given port is not indented, and subsequent lines pertaining to the same port are indented.
Next, examine the switch lines. The first few look like this:
## Switches
#set_property PACKAGE_PIN V17 [get_ports {sw[0]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
#set_property PACKAGE_PIN V16 [get_ports {sw[1]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
#set_property PACKAGE_PIN W16 [get_ports {sw[2]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]Uncomment all the set_property lines related to the
switches. Next, edit each line replacing sw[] with a
port name from your module. You should make the following
substitutions:
sw[0]
through sw[6]
to a[0]
through a[6]
(respectively)sw[7]
through sw[13]
to b[0]
through b[6]
(respectively)sw[14]
and sw[15]
to op[1]
and op[0]
(respectively)Next move down to the LEDs. Uncomment the set_property lines and change led[0]
through led[6]
to q[0]
through q[6],
respectively.
When finished, run make implement to build the design.
Program it onto the Basys3 board. When programmed, you should test the
following:
baDemonstrate one working condition for each op value. Photograph it and place the
photo in your working directory, with filenames case1, case2, and so on (with an appropriate
graphics file extention).
When finished, turn in your work using git:
git add src/* test_result.txt case* *.rpt *.bit
git commit . -m "Complete."
git push origin mainThen indicate on Canvas that your work is complete.