Verilog V4
Verilog V4
Abdallah El Ghamry
Simulation
assign Y = ~A;
endmodule
Buffer Gate
assign Y = ~(~A);
endmodule
AND Gate
A logic gate that produces a HIGH output only when all of the inputs
are HIGH.
assign Y = A & B;
endmodule
OR Gate
A logic gate that produces a HIGH output when one or more inputs
are HIGH.
assign Y = A | B;
endmodule
NAND Gate
A logic gate that produces a LOW output only when all the inputs
are HIGH.
A logic gate in which the output is LOW when one or more of the
inputs are HIGH.
A logic gate that produces a HIGH output only when its two inputs
are at opposite levels.
assign Y = A ^ B;
endmodule
Exclusive-NOR (XNOR) Gate
A logic gate that produces a LOW only when the two inputs are at
opposite levels.
assign Y1 = ~A | ~B;
assign Y2 = ~(A & B);
endmodule
Quiz: Multiple-Input Gates
Write SystemVerilog code to implement the following functions in hardware:
Four-input AND gate.
module AND4(A, B, C, D, Y);
input A, B, C, D;
output Y;
assign Y = A & B & C & D;
endmodule
Three-input NOR gate.
module NOR3(A, B, C, Y);
input A, B, C;
output Y;
assign Y = ~(A | B | C);
endmodule
Logic Gates Summary
AND-OR-Inverter (AOI) Gate
assign AB = A & B;
assign CD = C & D;
assign O = AB | CD;
assign F = ~O;
endmodule
Wire Assignments
assign F = (A & B) | C;
endmodule
module AND2_DUT();
reg A, B; // Registers
wire Y;
initial begin
A=1; B=1; #100; // Delay 100ps
A=0; B=1; #100; // Delay 100ps vsim AND2_DUT
A=1; B=0; #100; // Delay 100ps
A=0; B=0; #100; // Delay 100ps
end
initial begin
A=0; B=0; #100; // Delay 100ps
A=0; B=1; #100; // Delay 100ps
A=1; B=0; #100; // Delay 100ps
A=1; B=1; #100; // Delay 100ps
end
Gates
and, nand, or, nor, xor, xnor, buf, not
Pulls, tristate buffers
pullup, pulldown, bufif0, bufif1, notif0, notif1
Switches
cmos, nmos, ... tran, ...
AND8
initial begin
A=0; B=0; #200; // Delay 200ps
A=0; B=1; #200; // Delay 200ps
A=1; B=0; #200; // Delay 200ps
A=1; B=1; #200; // Delay 200ps
A=0; B=0; #200; // Delay 200ps
end
g=0 g=1
d d d
nMOS g OFF
ON
s s s
s s s
pMOS g OFF
ON
d d d
*NOT Gate Built With CMOS Transistors
supply1 VDD;
supply0 GND;
supply1 VDD;
supply0 GND;
wire X;
supply1 VDD;
supply0 GND;
wire X;
Hardware
ASIC
Reconfigurable Architectures
Software • CPLD
• FPGA
• µProcessor • Customized Processors
• µController • Coarse Grain
• DSP - Reconfigurable Array
D
C
B
A
The BCD-to-7-Segment Decoder
The BCD-to-7-Segment Decoder
https://www.electronicshub.org/bcd-7-segment-led-display-decoder-circuit/
7-Segment
input A, B, C, D;
output led_a, led_b, led_c, led_d, led_e, led_f, led_g;
Output ABCD
Verilog Basics
Verilog Logic Values
A vector is a row of logic values.
Verilog logic values are:
1’b0 - logic 0, false, ground
1’b1 - logic 1, true, power
1’bX - unknown or uninitialized
1’bZ - high impedance, floating
The value 1 (indicating a single bit)
'b stands for "binary"
Part Selects
Numbers
Numbers
Underscores (_) are used for formatting only to make it easier to read.
SystemVerilog ignores them.
Vector values can be written as integer literals, consisting of strings of
0s, 1s, Xs and Zs
Truncation and Extension
Truncation and Extension
If all the digits of a number are not specified, the most significant bits
are filled with zeroes. For example, 8'o77 represents 8'b00_111_111.
However, if the leftmost digit is X or Z, the missing bits are filled with
Xs or Zs respectively.
The values of regs and wires are considered to be unsigned quantities,
even though negative numbers may be used in expressions.
“Disguised” Binary Numbers
10 and -3 is a 32-bit decimal number and not a two bit binary one!
-3 will be represented in two's complement format.
Strings are converted to vectors by using the 8-bit ASCII code for each character
SystemVerilog Numbers
8-bit Unsigned Addition
8-bit Unsigned Addition
assign Y = A + B;
endmodule
8-bit Unsigned Addition Testbench
module UADD8_DUT();
reg [7:0] A, B;
wire [7:0] Y;
initial begin
// 0000 0101 + 0000 0011 = 0000 1000 (5 + 3 = 8)
A = 5; B = 3; #100;
// 0110 1111 + 0000 0111 = 0111 0110 (111 + 7 = 118)
A = 111; B = 8'b111; #100;
// 1100 1000 + 0000 1010 = 1101 0010 (200 + 10 = 210)
A = 200; B = 8'b0000_1010; #100;
end
initial begin
$monitor("%b + %b = %b \t %d + %d = %d", A, B, Y, A, B, Y);
end
endmodule
8-bit Signed Addition
assign Y = A + B;
endmodule
8-bit Signed Addition Testbench
module SADD8_DUT();
reg signed [7:0] A, B;
wire signed [7:0] Y;
initial begin
// 0000 0101 + 0000 0011 = 0000 1000 (5 + 3 = 8)
A = 5; B = 3; #100;
// 0110 1111 + 0000 0111 = 0111 0110 (111 + 7 = 118)
A = 111; B = 8'b111; #100;
// 1100 1000 + 0000 1010 = 1100 1001 (-56 + 10 = -46)
A = 200; B = 8'b0000_1010; #100;
end
initial begin
$monitor("%b + %b = %b \t %d + %d = %d", A, B, Y, A, B, Y);
end
endmodule
8-bit 1’s Complement With Testbench
module Complement1s (A, Y);
input [7:0] A;
output [7:0] Y;
assign Y = ~A;
endmodule
module Complement1s_DUT();
reg [7:0] A;
wire [7:0] Y;
initial begin
A = 8'b1100_1001; #200;
A = 8'b1111_1111; #200;
A = 8'b0000_1111; #200;
A = 8'b0011_1100; #200;
end
initial
CLK = 0;
always
#50 CLK = ~CLK;
endmodule
Always
module ClockGen_DUT2();
wire CLK;
ClockGen CG1 (CLK);
initial
#500 $stop;
initial
#1000 $finish;
endmodule
$stop and $finish
initial begin
reset = 1; #50;
reset = 0;
end
Q
debounced_clk
clk Clock slow_clk
Divider
Logical Shifter
Shifts the number to the left (LSL) or right (LSR) and fills
empty spots with 0’s.
00010100 << 2
0 0 0 1 0 1 0 0 20 10
* 22
0 1 0 1 0 0 0 0 80 10
Logical Shift Right
00010100 >> 2
0 0 0 1 0 1 0 0 20 10
/ 22
0 0 0 0 0 1 0 1 5 10
10-bit One-Hot Counter
In the case of a 10-bit ring counter, there is a unique output for each
decimal digit.
10-bit One-Hot Counter
D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
10-bit Up/Down One-Hot Counter
D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
10-bit Up/Down One-Hot Counter FSM
10-bit Up/Down One-Hot Counter FSM
module one_hot_counter_fsm (clk, reset, D);
input clk, reset;
Output reg [9:0] D;
parameter S0 = 2'b00, // initial state
S1 = 2'b01, // shift left state
S2 = 2'b10; // shift right state
reg [1:0] State;
initial
begin
clk = 0;
reset = 1; #100;
reset = 0;
end
always
#100 clk = ~clk;
vsim fsm_dut
add wave -position insertpoint sim:/fsm_dut/*
run 5000
10-bit Up/Down One-Hot Counter FSM
Output
Reset
One-Hot Counter FSM FPGA Implementation
ALU
ALU
always @(bcd)
begin
case(bcd)
4'b0000 : dec = ~7'b1111110; // 0
4'b0001 : dec = ~7'b0110000; // 1
4'b0010 : dec = ~7'b1101101; // 2
4'b0011 : dec = ~7'b1111001; // 3
4'b0100 : dec = ~7'b0110011; // 4
4'b0101 : dec = ~7'b1011011; // 5
4'b0110 : dec = ~7'b1011111; // 6
4'b0111 : dec = ~7'b1110000; // 7
4'b1000 : dec = ~7'b1111111; // 8
4'b1001 : dec = ~7'b1111011; // 9
4'b1010 : dec = ~7'b1110111; // A
4'b1011 : dec = ~7'b0011111; // b
4'b1100 : dec = ~7'b1001000; // =
default : dec = ~7'b1111110; // 0
endcase
end
endmodule
ALU
module ALU (A, B, F, Y);
input [1:0] A, B;
input [2:0] F;
output reg [3:0] Y;
always @(*)
begin
case(F)
3'b000: Y = A & B;
3'b001: Y = A | B;
3'b010: Y = A + B;
3'b011: Y = A - B;
3'b100: Y = A * B;
3'b101: Y = A > B? 4'b1010 : 4'b1011;
3'b110: Y = A < B? 4'b1011 : 4'b1010;
3'b111: Y = A == B? 4'b1100 : 4'b0000;
default: Y = 4'b0000 ;
endcase
end
endmodule
ALU
wire [3:0] Y;