VHDL Examples Subra Ganesan Reference Professor Haskells Notes
VHDL Examples Subra Ganesan Reference: Professor Haskell’s Notes, Digital design with VHDL book by Vranesic
n-line 2 -to-1 Multiplexer a(n-1: 0) b(n-1: 0) n-line 2 x 1 MUX sel y(n-1: 0) sel y 0 a 1 b 2
An n-line 2 x 1 MUX a(n-1: 0) n-line 2 x 1 MUX library IEEE; b(n-1: 0) use IEEE. std_logic_1164. all; entity mux 2 g is sel generic (width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); b: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC; y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end mux 2 g; y(n-1: 0) 3
Entity Each entity must begin with these library and use statements library IEEE; use IEEE. std_logic_1164. all; generic statement defines entity mux 2 g is width of bus generic (width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); b: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC; y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end mux 2 g; port statement defines inputs and outputs 4
Entity Mode: in or out library IEEE; use IEEE. std_logic_1164. all; entity mux 2 g is generic (width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); b: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC; y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end mux 2 g; Data type: STD_LOGIC, STD_LOGIC_VECTOR(width-1 downto 0); 5
Standard Logic library IEEE; use IEEE. std_logic_1164. all; type std_ulogic is ( ‘U’, ‘X’ ‘ 0’ ‘ 1’ ‘Z’ ‘W’ ‘L’ ‘H’ ‘-’); -- Uninitialized -- Forcing unknown -- Forcing zero -- Forcing one -- High impedance -- Weak unknown -- Weak zero -- Weak one -- Don’t care 6
Standard Logic Type std_ulogic is unresolved. Resolved signals provide a mechanism for handling the problem of multiple output signals connected to one signal. subtype std_logic is resolved std_ulogic; 7
Architecture architecture mux 2 g_arch of mux 2 g is begin mux 2_1: process(a, b, sel) begin a(n-1: 0) if sel = '0' then y <= a; else b(n-1: 0) y <= b; end if; end process mux 2_1; end mux 2 g_arch; n-line 2 x 1 MUX y(n-1: 0) sel Note: <= is signal assignment 8
Architecture entity name process sensitivity architecture mux 2 g_arch of mux 2 g is list begin mux 2_1: process(a, b, sel) begin Sequential statements if sel = '0' then y <= a; (if…then…else) must be else in a process y <= b; end if; end process mux 2_1; end mux 2 g_arch; Note begin…end in architecture Note begin…end in process 9
library IEEE; use IEEE. STD_LOGIC_1164. all; use IEEE. std_logic_unsigned. all; Top-level design for Lab 1 entity Lab 1 is port( SW : in STD_LOGIC_VECTOR(7 downto 0); BTN 0 : in STD_LOGIC; LD : out STD_LOGIC_VECTOR(3 downto 0) ); end Lab 1; 10
architecture Lab 1_arch of Lab 1 is component mux 2 g generic( width : POSITIVE); port( a : in std_logic_vector((width-1) downto 0); b : in std_logic_vector((width-1) downto 0); sel : in std_logic; y : out std_logic_vector((width-1) downto 0)); end component; constant bus_width: integer : = 4; begin mux 2: mux 2 g generic map(width => bus_width) port map (a => SW(7 downto 4), b => SW(3 downto 0), sel => BTN 0, y => LD); end Lab 1_arch; 11
Example of case statement architecture mux 4 g_arch of mux 4 g is begin process (sel, a, b, c, d) begin case sel is when "00" => y <= a; when "01" => y <= b; when "10" => y <= c; when others => y <= d; end case; end process; end mux 4 g_arch; Note implies operator => Sel “ 00” “ 01” “ 10” “ 11” y a b c d Must include ALL possibilities in case statement 12
7 -Segment Display Truth table D a b c d e f g 0 1 1 1 0 0 2 1 1 0 1 3 1 1 0 0 1 4 0 1 1 0 0 1 1 5 1 0 1 1 6 1 0 1 1 1 7 1 1 1 0 0 D(3: 0) seg 7 dec Ato. G(6: 0) D a b c d e f g 8 1 1 1 1 9 1 1 0 1 1 A 1 1 1 0 1 1 1 b 0 0 1 1 1 C 1 0 0 1 1 1 0 d 0 1 1 0 1 E 1 0 0 1 1 F 1 0 0 0 1 13
7 -Segment Display Verilog Behavior D(3: 0) seg 7 dec case(D) 0: Ato. G = 7'b 1111110; 1: Ato. G = 7'b 0110000; 2: Ato. G = 7'b 1101101; 3: Ato. G = 7'b 1111001; 4: Ato. G = 7'b 0110011; 5: Ato. G = 7'b 1011011; 6: Ato. G = 7'b 1011111; 7: Ato. G = 7'b 1110000; 8: Ato. G = 7'b 1111111; 9: Ato. G = 7'b 1111011; 'h. A: Ato. G = 7'b 1110111; 'hb: Ato. G = 7'b 0011111; 'h. C: Ato. G = 7'b 1001110; 'hd: Ato. G = 7'b 0111101; Ato. G(6: 0) 'h. E: Ato. G = 7'b 1001111; 'h. F: Ato. G = 7'b 1000111; default: Ato. G = 7'b 1111110; // 0 endcase 14
7 -Segment Display VHDL -- seg 7 dec with digit select ssg <= "1001111" when "0001", --1 "0010010" when "0010", --2 "0000110" when "0011", --3 Ato. G "1001100" when "0100", --4 "0100100" when "0101", --5 "0100000" when "0110", --6 "0001111" when "0111", --7 "0000000" when "1000", --8 "0000100" when "1001", --9 "0001000" when "1010", --A "1100000" when "1011", --b "0110001" when "1100", --C "1000010" when "1101", --d sseg(6: 0) "0110000" when "1110", --E seg 7 dec "0111000" when "1111", --F "0000001" when others; --0 Behavior (Active LOW) digit(3: 0) 15
Comparators Recall that an XNOR gate can be used as an equality detector XNOR X Y Z = !(X $ Y) Z = X xnor Y Z = ~(X @ Y) Z if X = Y then Z <= '1'; else Z <= '0'; end if; X 0 0 1 1 Y 0 1 Z 1 0 0 1 16
4 -Bit Equality Comparator A: in STD_LOGIC_VECTOR(3 downto 0); B: in STD_LOGIC_VECTOR(3 downto 0); A_EQ_B: out STD_LOGIC; 17
library IEEE; use IEEE. STD_LOGIC_1164. ALL; use IEEE. STD_LOGIC_ARITH. ALL; use IEEE. STD_LOGIC_UNSIGNED. ALL; entity eqdet 4 is Port ( A : in std_logic_vector(3 downto 0); B : in std_logic_vector(3 downto 0); A_EQ_B : out std_logic); end eqdet 4; architecture Behavioral of eqdet 4 is signal C: std_logic_vector(3 downto 0); begin C <= A xnor B; A_EQ_B <= C(0) and C(1) and C(2) and C(3); end Behavioral; 18
Comparators A_EQ_B A(n-1: 0) A_GT_B comp B(n-1: 0) A_LT_B A_UGT_B A_ULT_B A, B signed A, B unsigned Signed: 2's complement signed numbers 19
-- Comparator for unsigned and signed numbers library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_arith. all; use IEEE. std_logic_unsigned. all; A(n-1: 0) B(n-1: 0) comp A_EQ_B A_GT_B A_LT_B A_UGT_B A_ULT_B entity comp is generic(width: positive); port ( A: in STD_LOGIC_VECTOR(width-1 downto 0); B: in STD_LOGIC_VECTOR(width-1 downto 0); A_EQ_B: out STD_LOGIC; A_GT_B: out STD_LOGIC; A_LT_B: out STD_LOGIC; A_UGT_B: out STD_LOGIC ); end comp; 20
architecture comp_arch of comp is begin CMP: process(A, B) variable AVS, BVS: signed(width-1 downto 0); begin for i in 0 to width-1 loop AVS(i) : = A(i); BVS(i) : = B(i); end loop; A(n-1: 0) A_EQ_B <= '0'; A_GT_B <= '0'; A_LT_B <= '0'; B(n-1: 0) A_ULT_B <= '0'; A_UGT_B <= '0'; if (A = B) then A_EQ_B <= '1'; end if; if (AVS > BVS) then A_GT_B <= '1'; end if; if (AVS < BVS) then A_LT_B <= '1'; end if; if (A > B) then A_UGT_B <= '1'; end if; if (A < B) then A_ULT_B <= '1'; end if; end process CMP; end comp_arch; comp A_EQ_B A_GT_B A_LT_B A_UGT_B A_ULT_B Note: All outputs must be assigned some value. The last signal assignment in a process is the value assigned 21
4 -Bit Comparator 22
Full Adder Truth table Ci Ai Bi Si Ci+1 Behavior Ci+1: Si = Ci + Ai + Bi 23
Full Adder Block Diagram 24
4 -Bit Adder C 1 1 1 0 0: A 0 1 1 0: B 0 0 1 1 1 C 4: S 1 0 0 25
library IEEE; use IEEE. STD_LOGIC_1164. all; use IEEE. STD_LOGIC_unsigned. all; entity adder 4 is port( A : in STD_LOGIC_VECTOR(3 downto 0); B : in STD_LOGIC_VECTOR(3 downto 0); carry : out STD_LOGIC; S : out STD_LOGIC_VECTOR(3 downto 0) ); end adder 4; architecture adder 4 of adder 4 is begin process(A, B) variable temp: STD_LOGIC_VECTOR(4 downto 0); begin temp : = ('0' & A) + ('0' & B); S <= temp(3 downto 0); carry <= temp(4); end process; end adder 4; 26
4 -Bit Adder 27
3 -to-8 Decoder A: in STD_LOGIC_VECTOR(2 downto 0); Y: out STD_LOGIC_VECTOR(0 to 7); Behavior for i in 0 to 7 loop if(i = conv_integer(A)) then Y(i) <= ‘ 1’; else Y(i) <= ‘ 0’; end if; end loop; 28
library IEEE; use IEEE. STD_LOGIC_1164. all; use IEEE. STD_LOGIC_arith. all; use IEEE. STD_LOGIC_unsigned. all; 3 -to-8 Decoder entity decode 38 is port( A : in STD_LOGIC_VECTOR(2 downto 0); Y : out STD_LOGIC_VECTOR(0 to 7) ); end decode 38; architecture decode 38 of decode 38 is begin process(A) variable j: integer; begin j : = conv_integer(A); for i in 0 to 7 loop if(i = j) then Y(i) <= '1'; else Y(i) <= '0'; end if; end loop; end process; end decode 38; 29
Shifters Shift right Shift left Arithmetic shift right 30
shift 4. vhd library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_unsigned. all; entity shifter is generic(width: positive : = 4); port ( D: in STD_LOGIC_VECTOR(width-1 downto 0); s: in STD_LOGIC_VECTOR(1 downto 0); Y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end shifter; 31
architecture shifter_arch of shifter is begin shift_1: process(D, s) begin case s is when "00" => -- no shift Y <= D; when "01" => -- U 2/ Y <= '0' & D(width-1 downto 1); when "10" => -- 2* Y <= D(width-2 downto 0) & '0'; when "11" => -- 2/ Y <= D(width-1) & D(width-1 downto 1); when others => -- no shift Y <= D; end case; end process shift_1; end shifter_arch; 32
Code Converters • Gray Code Converter • Binary-to-BCD Converter 33
Gray Code Definition: An ordering of 2 n binary numbers such that only one bit changes from one entry to the next. Binary coding {0. . . 7}: {000, 001, 010, 011, 100, 101, 110, 111} Gray coding {0. . . 7}: {000, 001, 010, 111, 100} Not unique One method for generating a Gray code sequence: Start with all bits zero and successively flip the right-most bit that produces a new string. 34
Binary - Gray Code Conversions Gray code: G(i), i = n – 1 downto 0 Binary code: B(i), i = n – 1 downto 0 Binary coding {0. . . 7}: {000, 001, 010, 011, 100, 101, 110, 111} Gray coding {0. . . 7}: {000, 001, 010, 111, 100} Convert Binary to Gray: Copy the most significant bit. For each smaller i G(i) = B(i+1) xor B(i) Convert Gray to Binary: Copy the most significant bit. For each smaller i B(i) = B(i+1) xor G(i) 35
library IEEE; use IEEE. STD_LOGIC_1164. all; bin 2 gray. vhd entity bin 2 gray is generic(width: positive : = 3); port( B : in STD_LOGIC_VECTOR(width-1 downto 0); G : out STD_LOGIC_VECTOR(width-1 downto 0) ); end bin 2 gray; architecture bin 2 gray of bin 2 gray is begin process(B) begin G(width-1) <= B(width-1); for i in width-2 downto 0 loop G(i) <= B(i+1) xor B(i); end loop; end process; end bin 2 gray; 36
library IEEE; use IEEE. STD_LOGIC_1164. all; gray 2 bin. vhd entity gray 2 bin is generic(width: positive : = 3); port( G : in STD_LOGIC_VECTOR(width-1 downto 0); B : out STD_LOGIC_VECTOR(width-1 downto 0) ); end gray 2 bin; architecture gray 2 bin of gray 2 bin is begin process(G) variable BV: STD_LOGIC_VECTOR(width-1 downto 0); begin BV(width-1) : = G(width-1); for i in width-2 downto 0 loop BV(i) : = BV(i+1) xor G(i); end loop; B <= BV; end process; end gray 2 bin; 37
Binary-to-BCD Conversion • Shift and add 3 algorithm • RTL solution • Behavioral solution 38
Shift and Add-3 Algorithm 11. Shift the binary number left one bit. 22. If 8 shifts have taken place, the BCD number is in the Hundreds, Tens, and Units column. 33. If the binary value in any of the BCD columns is 5 or greater, add 3 to that value in that BCD column. 44. Go to 1. 39
Steps to convert an 8 -bit binary number to BCD 40
Truth table for Add-3 Module A 3 A 2 A 1 A 0 C S 3 S 2 S 1 S 0 41
Binary-to-BCD Converter RTL Solution 42
Binary-to-BCD Converter: Behavioral Solution -- Title: Binary-to-BCD Converter library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_unsigned. all; entity binbcd is port ( B: in STD_LOGIC_VECTOR (7 downto 0); P: out STD_LOGIC_VECTOR (9 downto 0) ); end binbcd; 43
architecture binbcd_arch of binbcd is begin bcd 1: process(B) variable z: STD_LOGIC_VECTOR (17 downto 0); begin for i in 0 to 17 loop z(i) : = '0'; end loop; z(10 downto 3) : = B; for i in 0 to 4 loop if z(11 downto 8) > 4 then z(11 downto 8) : = z(11 downto 8) + 3; end if; if z(15 downto 12) > 4 then z(15 downto 12) : = z(15 downto 12) + 3; end if; z(17 downto 1) : = z(16 downto 0); end loop; P <= z(17 downto 8); end process bcd 1; end binbcd_arch; 44
16 -bit Binary-to-BCD Converter 45
Verilog binbcd module binbcd(B, P); input [15: 0] B; output [15: 0] P; reg [31: 0] z; integer i; 46
always @(B) begin for(i = 0; i <= 31; i = i+1) z[i] = 0; z[18: 3] = B; for(i = 0; i <= 12; i = i+1) begin if(z[19: 16] > 4) z[19: 16] = z[19: 16] + 3; if(z[23: 20] > 4) z[23: 20] = z[23: 20] + 3; if(z[27: 24] > 4) z[27: 24] = z[27: 24] + 3; if(z[31: 28] > 4) z[31: 28] = z[31: 28] + 3; z[31: 1] = z[30: 0]; end P = z[31: 16]; endmodule 47
Arithmetic Logic Units • ALU 1 – Shifting, Increment and Decrement Instructions • ALU 2 – Arithmetic and Logic Instructions • ALU 3 – Comparators 48
ALU 1 Shifting, Increment and Decrement Instructions Sel y Name '000' a+1 1+ '001' a-1 1 - '010' not a invert '011' LSL a 2* '100' LSR a U 2/ '101' ASR a 2/ '110' All ones true '111' All zeros false 49
alu 1. vhd library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_unsigned. all; entity alu 1 is generic(width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC_VECTOR(2 downto 0); y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end alu 1; 50
architecture alu 1_arch of alu 1 is begin alu_1: process(a, sel) variable true, false: STD_LOGIC_VECTOR (width-1 downto 0); begin -- true is all ones; false is all zeros for i in 0 to width-1 loop true(i) : = '1'; false(i) : = '0'; end loop; case sel is when "000" => -- 1+ y <= a + 1; when "001" => -- 1 y <= a - 1; when "010" => -- invert y <= not a; when "011" => -- 2* y <= a(width-2 downto 0) & '0'; when "100" => -- U 2/ y <= '0' & a(width-1 downto 1); when "101" => -- 2/ y <= a(width-1) & a(width-1 downto 1); when "110" => -- TRUE y <= true; when others => -- FALSE y <= false; end case; end process alu_1; 51 end alu 1_arch;
ALU 2 Arithmetic and Logic Instructions Sel y Name '000' a+b + '001' b-a - '010' a and b AND '011' a or b OR '100' a xor b XOR '101' true if a = 0 false otherwise 0= '110' true if a < 0 false otherwise 0< '111' true if b > a false otherwise U> 52
alu 2. vhd library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_unsigned. all; entity alu 2 is generic(width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); b: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC_VECTOR(2 downto 0); y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end alu 2; 53
architecture alu 2_arch of alu 2 is begin alu_2: process(a, b, sel) variable true, false: STD_LOGIC_VECTOR (width-1 downto 0); variable Z: STD_LOGIC; begin Z : = '0'; for i in 0 to width-1 loop true(i) : = '1'; -- true is all ones; false(i) : = '0'; -- false is all zeros Z : = Z or a(i); -- Z = '0' if all a(i) = '0' end loop; case sel is when "000" => y <= a + b; when "001" => y <= b - a; when "010" => y <= a and b; when "011" => y <= a or b; when "100" => y <= A xor B; -- + -- -- AND -- OR -- XOR 54
when "101" => if (Z = '0') then y <= true; else y <= false; end if; -- 0= NOT when "110" => -- 0< if (a(width-1) = '1') then y <= true; else y <= false; end if; when "111" => -- U> if (b > a) then y <= true; else y <= false; end if; when others => null; end case; end process alu_2; end alu 2_arch; 55
ALU 3 Comparators Sel y Name '000' true if b = a false otherwise = '001' true if b /= a false otherwise <> '010' true if b < a (unsigned) false otherwise U< '011' true if b > a (unsigned) false otherwise U> '100' true if b <= a (unsigned) false otherwise U<= '101' true if b < a (signed) false otherwise < '110' true if b > a (signed) false otherwise > '111' true if b <= a (signed) false otherwise <= 56
alu 3. vhd library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_arith. all; use IEEE. std_logic_unsigned. all; entity alu 3 is generic(width: positive); port ( a: in STD_LOGIC_VECTOR(width-1 downto 0); b: in STD_LOGIC_VECTOR(width-1 downto 0); sel: in STD_LOGIC_VECTOR(2 downto 0); y: out STD_LOGIC_VECTOR(width-1 downto 0) ); end alu 3; 57
architecture alu 3_arch of alu 3 is begin alu_3: process(a, b, sel) variable true, false: STD_LOGIC_VECTOR (width-1 downto 0); variable avs, bvs: signed(width-1 downto 0); begin for i in 0 to width-1 loop true(i) : = '1'; -- true is all ones; false(i) : = '0'; -- false is all zeros avs(i) : = a(i); bvs(i) : = b(i); end loop; case sel is when "000" => if (a = b) then y <= true; else y <= false; end if; -- = 58
when "001" => if (a /= b) then y <= true; else y <= false; end if; -- <> when "010" => if (b < a) then y <= true; else y <= false; end if; -- U< when "011" => if (b > a) then y <= true; else y <= false; end if; when "100" => if (b <= a) then y <= true; else y <= false; end if; -- U> -- U<= 59
when "101" => if (bvs < avs) then y <= true; else y <= false; end if; when "110" => if (bvs > avs) then y <= true; else y <= false; end if; when "111" => if (bvs <= avs) then y <= true; else y <= false; end if; when others => null; end case; end process alu_3; end alu 3_arch; -- < -- > -- <= 60
ROM addr(2: 0) 0 1 2 3 4 5 6 7 85 C 4 E 6 55 67 D 4 F 4 C 6 M(7: 0) 61
ROM. vhd library IEEE; use IEEE. std_logic_1164. all; use IEEE. std_logic_unsigned. all; entity ROM is port ( addr: in STD_LOGIC_VECTOR (2 downto 0); M: out STD_LOGIC_VECTOR (7 downto 0) ); end ROM; addr(2: 0) 0 1 2 3 4 5 6 7 85 C 4 E 6 55 67 D 4 F 4 C 6 M(7: 0) 62
architecture ROM_arch of ROM is constant data 0: STD_LOGIC_VECTOR (7 downto 0) : = "10000101"; constant data 1: STD_LOGIC_VECTOR (7 downto 0) : = "11000100"; constant data 2: STD_LOGIC_VECTOR (7 downto 0) : = X"E 6"; constant data 3: STD_LOGIC_VECTOR (7 downto 0) : = X"55"; constant data 4: STD_LOGIC_VECTOR (7 downto 0) : = X"67"; constant data 5: STD_LOGIC_VECTOR (7 downto 0) : = X"D 4"; constant data 6: STD_LOGIC_VECTOR (7 downto 0) : = "11110100"; constant data 7: STD_LOGIC_VECTOR (7 downto 0) : = "11000110"; type rom_array is array (NATURAL range <>) of STD_LOGIC_VECTOR (7 downto 0); constant rom: rom_array : = ( data 0, data 1, data 2, data 3, data 4, data 5, data 6, data 7 ); begin 0 85 process(addr) variable j: integer; 1 C 4 begin 2 E 6 j : = conv_integer(addr); 3 55 addr(2: 0) M(7: 0) M <= rom(j); 4 67 end process; 5 D 4 end ROM_arch; 6 7 F 4 C 6 63
architecture alu 3_arch of alu 3 is begin alu_3: process(a, b, sel) variable true, false: STD_LOGIC_VECTOR (width-1 downto 0); variable avs, bvs: signed(width-1 downto 0); begin for i in 0 to width-1 loop true(i) : = '1'; -- true is all ones; false(i) : = '0'; -- false is all zeros avs(i) : = a(i); bvs(i) : = b(i); end loop; case sel is when "000" => if (a = b) then y <= true; else y <= false; end if; -- = 64
- Slides: 64