Tổng hợp các bài tập mẫu hay viết bằng ngôn ngữ mô tả phần cứng VHDL
Trang 1ĐHBK Tp HCM–Khoa ĐĐT–BMĐT
Môn học: Kỹ thuật số
GVPT: Hồ Trung Mỹ
Bài tập giải sẵn về VHDL (AY1112-S1)
(Các mã VHDL đã được chạy thử trên Altera MaxplusII v10.2)
1 Viết mã VHDL để đếm số bit 1 của số nhị phân 3 bit A với các cách sau:
port ( A : in std_logic_vector(2 downto 0);
C : out std_logic_vector(1 downto 0));
end ONES_CNT_EX1;
a) Mô hình hành vi:
architecture Algorithmic of ONES_CNT_EX1 is begin
Process(A) Sensitivity List Contains only Vector A
Variable num: INTEGER range 0 to 3;
begin
For i in 0 to 2
Trang 2Combinatorial Process Statement
Copyright (c) 1994 Altera Corporation
ENTITY proc IS PORT (
BEGIN
Trang 3num_bits := 0;
FOR i IN d'RANGE LOOP
IF d(i) = '1' THEN num_bits := num_bits + 1;
b) Mô hình luồng dữ liệu
architecture Two_Level of ONES_CNT_EX2 is
begin
C(1) <= (A(1) and A(0)) or (A(2) and A(0))
or (A(2) and A(1));
C(0) <= (A(2) and not A(1) and not A(0))
or (not A(2) and not A(1) and A(0))
or (A(2) and A(1) and A(0))
or (not A(2) and A(1) and not A(0));
Trang 4Có nhiều cách giải cho phần này
Từ bảng chân trị ta có biểu thức Boole cho các ngõ ra:
C1 = A1A0 + A0A2 + A1A2 + A0A1A2
C1 = A1A0 + A0A2 + A1A2 => cần AND 2 ngõ vào và OR 3 ngõ vào
và
C0 = A2’A1’A0 + A2’A1A0’ + A2A1’A0’ + A2A1A0
C0 = ((A2’A1’A0)’.( A2’A1A0’)’ (A2A1’A0’)’.(A2A1A0)’)’
=> Cần NAND 3 ngõ vào, NAND 4 ngõ vào và cổng NOT Mạch cho C1 được đặt tên là MAJ3 và mạch cho C0 được đặt tên là OPAR3
Từ đó có bài giải sau:
Trang 5PORT( I1, I2: in STD_LOGIC; Declare Components
O: out STD_LOGIC); To Be Instantiated
Trang 6g1: and2gate PORT MAP (X(0), X(1), A1);
g2: and2gate PORT MAP (X(0), X(2), A2); Wiring of g3: and2gate PORT MAP (X(1), X(2), A3); Maj3
g4: or3gate PORT MAP (A1, A2, A3, Z); Compts
end Structural_M;
-OPAR3 Circuit - LIBRARY IEEE;
g1: notgate PORT MAP (X(0), A0B);
g2: notgate PORT MAP (X(1), A1B);
g3: notgate PORT MAP (X(2), A2B);
g4: nand3gate PORT MAP (X(2), A1B, A0B, Z1);
g5: nand3gate PORT MAP (X(0), A1B, A2B, Z2);
g6: nand3gate PORT MAP (X(0), X(1), X(2), Z3);
g7: nand3gate PORT MAP (X(1), A2B, A0B, Z4);
Trang 7g8: nand4gate PORT MAP (Z1, Z2, Z3, Z4, Z);
port ( A : in STD_LOGIC_VECTOR(2 downto 0);
C : out STD_LOGIC_VECTOR(1 downto 0));
c1: MAJ3 PORT MAP (A, C(1));
c2: OPAR3 PORT MAP (A, C(0));
Các cổng logic của Maxplus II có các khai báo sau:
1) Cổng NOT với tên là A_NOT có khai báo sau:
COMPONENT a_not
PORT( a_in: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
Trang 82) Cổng AND có thể có n ngõ vào (ANDn) với n=2, 3, 4, 6, 8 và 12
TD: Khai báo sau cho cổng AND có 2 ngõ vào:
COMPONENT and2
PORT( IN1, IN2: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
3) Cổng OR có thể có n ngõ vào (ORn) với n=2, 3, 4, 6, 8 và 12
TD: Khai báo sau cho cổng OR có 2 ngõ vào:
COMPONENT or3
PORT(IN1, IN2, IN3: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
4) Cổng NAND có thể có n ngõ vào (NANDn) với n=2, 3, 4, 6, 8 và 12
5) Cổng NOR có thể có n ngõ vào (NANDn) với n=2, 3, 4, 6, 8 và 12
6) Cổng XOR 2 ngõ vào có tên là a_XOR với khai báo sau:
COMPONENT a_xor
PORT(IN1, IN2: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
7) Cổng XNOR 2 ngõ vào có tên là a_XNOR
Như vậy ta có lời giải khác ngắn hơn nếu sử dụng các component có sẵn của Maxplus II:
- Use built-in components of MaxplusII
- Majority of 3 bit number - LIBRARY IEEE;
PORT( IN1, IN2: in STD_LOGIC; Declare Components
a_out: out STD_LOGIC); To Be Instantiated END COMPONENT;
COMPONENT or3
PORT(IN1, IN2, IN3: in STD_LOGIC;
a_out: out STD_LOGIC);
g1: and2 PORT MAP (X(0), X(1), A1);
g2: and2 PORT MAP (X(0), X(2), A2); Wiring of g3: and2 PORT MAP (X(1), X(2), A3); Maj3
Trang 9g4: or3 PORT MAP (A1, A2, A3, Z); Compts
PORT( a_in: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
COMPONENT nand3
PORT( IN1, IN2, IN3: in STD_LOGIC;
a_out: out STD_LOGIC);
END COMPONENT;
COMPONENT nand4
PORT( IN1, IN2, IN3, IN4: in STD_LOGIC;
a_out: out STD_LOGIC);
g1: a_not PORT MAP (X(0), A0B);
g2: a_not PORT MAP (X(1), A1B);
g3: a_not PORT MAP (X(2), A2B);
g4: nand3 PORT MAP (X(2), A1B, A0B, Z1);
g5: nand3 PORT MAP (X(0), A1B, A2B, Z2);
g6: nand3 PORT MAP (X(0), X(1), X(2), Z3);
g7: nand3 PORT MAP (X(1), A2B, A0B, Z4);
g8: nand4 PORT MAP (Z1, Z2, Z3, Z4, Z);
port ( A : in STD_LOGIC_VECTOR(2 downto 0);
C : out STD_LOGIC_VECTOR(1 downto 0));
end ONES_CNT_EX4B;
architecture Structural of ONES_CNT_EX4B is
Trang 10c1: MAJ3 PORT MAP (A, C(1));
c2: OPAR3 PORT MAP (A, C(0));
1) Lệnh đồng thời với phép gán dùng các toán tử logic
- signal assignment with logic operators library ieee;
use ieee.std_logic_1164.all;
entity Q02_1 is port ( A, B, C: in std_logic; C: LSB F: out std_logic);
Trang 11D5 <= A and not(B) and C;
end a;
Trang 12if (ABC= "001" or ABC = "101" or ABC ="111") then
Trang 133 Hãy vẽ mạch logic tương ứng (không đơn giản hóa hàm Boole và có thể sử dụng các thành
phần tổ hợp cơ bản như cổng logic, mux, decoder, FA, HA, …) của mã VHDL sau:
library ieee;
use ieee.std_logic_1164.all;
entity blackbox is port(
a, b, cin: in std_logic;
inst: in std_logic_vector(2 downto 0);
F, cout: out std_logic);
s3 <= a xor s4 xor cin;
cout <= (a and s4) or ( s4 and cin) or (a and cin);
s3 <= a xor s4 xor cin;
cout <= (a and s4) or ( s4 and cin) or (a and cin);
nhằm thực hiện mạch FA, do đó có thể dùng khối này trong mạch logic
Process U1 chính là MUX 4 sang 1 với ngõ chọn là inst(2:1)
Process U2 chính là MUX 2 sang 1 với ngõ chọn là inst(0)
Từ đó ta có mạch logic của mã VHDL trên là: (ALU 1 bit)
Trang 144 Hãy vẽ mạch logic tương ứng (không đơn giản hóa hàm Boole và có thể sử dụng các thành
phần tổ hợp cơ bản như cổng logic, mux, decoder, FA, HA, …) của mã VHDL sau:
Trang 15Bài giải
Từ mã VHDL ta có thể viết trực tiếp các biểu thức Boole cho các biến ra với loại lệnh IF :
Lệnh Biểu thức Boole tương đương
Áp dụng qui tắc này ta tìm được biểu thức Boole cho Z:
Z = S(0).A + S(0)’(S(1).B + S(1)’.C) Nhớ lại với MUX 2 sang 1có ngõ ra Y và các ngõ vào I0, I1 và S thì ngõ ra là:
Y = S’.I0 + S.I1 Như vậy ta phải dùng 2 mạch MUX 2 sang 1 để thực hiện mạch trên:
5 Hãy vẽ mạch logic tương ứng (không đơn giản hóa hàm Boole và có thể sử dụng các thành
phần tổ hợp cơ bản như cổng logic, mux, decoder, FA, HA, …) của mã VHDL sau:
Trang 16 mạch mã hóa ưu tiên từ 10 ngõ vào (in_n) sang 4 (BCD): ngõ vào tích cực thấp và ưu
tiên bit có trọng số thấp nhất, ngõ ra là số BCD 4 bit chỉ ngõ vào nào được tích cực thấp
o TD: Ngõ vào in_n = 11111100 thì ngõ ra là BCD = 0000
Mạch giải mã BCD ra 7 đoạn nối với LED (giả sử logic 1 làm cho đoạn LED sáng) : mạch này nhận giá trị ra từ mạch trên và chuyển sang mã 7 đoạn hiện trên LED 7 đoạn a) Hãy viết mã VHDL với 2 mạch này độc lập
b) Hãy viết mã VHDL chỉ có 1 mạch duy nhất
in_n: in std_logic_vector(9 downto 0);
in_n : low active and higher priority LSB
LED_7seg: out std_logic_vector(6 downto 0));
s_BCD <= "0000" when (in_n(0) = '0') else
"0001" when in_n(1) = '0' else
"0010" when in_n(2) = '0' else
"0011" when in_n(3) = '0' else
"0100" when in_n(4) = '0' else
"0101" when in_n(5) = '0' else
"0110" when in_n(6) = '0' else
"0111" when in_n(7) = '0' else
"1000" when in_n(8) = '0' else
"1001" when in_n(9) = '0' else "1111"; invalid BCD
Trang 17BCD to 7 segment Decoder: LED_7seg = gfedcba
LED_7seg <= "0111111" when s_BCD = "0000" else
in_n: in std_logic_vector(9 downto 0);
LED_7seg: out std_logic_vector(6 downto 0));
end Q06_2;
architecture bg of Q06_2 is
begin
LED_7seg <= "0111111" when in_n(0) = '0' else
"0000110" when in_n(1) = '0' else
"1011011" when in_n(2) = '0' else
"1001111" when in_n(3) = '0' else
"1100110" when in_n(4) = '0' else
"1101101" when in_n(5) = '0' else
"1111101" when in_n(6) = '0' else
Trang 18"0000111" when in_n(7) = '0' else
"0000000" when in_n(8) = '0' else
"1101111" when in_n(9) = '0' else (others => '0');
end bg;
7 Thiết kế JK flipfop như hình bên dưới (các ngõ Preset PR và Clear CLR
tích cực cao và bất đồng bộ, CLR có ưu tiên cao hơn PR)
elsif rising_edge(CLK) then
Q_int <= (J and not Q_int) or (not K and Q_int);
Trang 19signal Q_int: std_logic;
signal JK: std_logic_vector(1 downto 0);
Trang 20Dạng sóng mô phỏng :
8 Thiết kế mạch cộng song song 2 số nhị phân N bit (dùng phát biểu generic để thiết kế tổng
quát, mặc nhiên N =4) là A và B Tổng là Sum và số nhớ/mượn là C_out
a) Mô tả VHDL cho mạch này
b) Thêm vào tín hiệu điều khiển cho phép cộng/trừ với tên là Add_Sub (0: cộng và 1:trừ) thì phải chỉnh sửa như thế nào?
C_out: out std_logic;
Sum: out std_logic_vector(N-1 downto 0));
end Q08_1;
architecture bg of Q08_1 is
signal Sum_int: std_logic_vector(Num downto 0);
begin
Sum_int <= ('0' & A) + ('0' & B);
Sum <= Sum_int(N-1 downto 0);
C_out <= Sum_int(N);
end bg;
b) Thêm tín hiệu điều khiển Add_Sub:
Ta chỉ cần định nghĩa thêm Add_sub và viết lại lệnh gán của Sum_int :
Sum_int <= ('0' & A) + ('0' & B) when Add_sub = '0' else
('0' & A) - ('0' & B);
Dạng sóng mô phỏng :
Trang 219 Thiết kế mạch cộng nối tiếp 2 số nhị phân với A và B có chiều dài là Num_bits bit (mặc nhiên cho Num_bits = 4)
Dữ liệu vào được nhập nối tiếp với LSB đi trước
Kết quả là tổng Sum có chiều dài Num_bits bit và có số nhớ ra là C_out
Tín hiệu Start =1 để chỉ bắt đầu thực hiện cộng (chỉ tồn tại < 1 chu kỳ xung nhịp)
Có tín hiệu Finished báo đã hoàn tất phép cộng
Mạch hoạt động theo cạnh xuống xung nhịp CLK
Hãy viết mã VHDL cho mạch này
C_out, Finished: out std_logic;
Sum: out std_logic_vector(Num_bits-1 downto 0));
end Q09_1;
architecture bg of Q09_1 is
begin
process(CLK, Start)
variable FIN: std_logic; Internal Finish signal
variable N: integer range 0 to Num_bits;
variable S, C_in: std_logic;
variable Sum_int: std_logic_vector(Num_bits-1 downto 0);
S := A xor B xor C_in;
C_in := (A and B) or ( B and C_in) or ( A and C_in); Sum_int:= S & Sum_int(Num_bits-1 downto 1);
N := N - 1;
Trang 22Thay dòng: variable S, C_in: std_logic; bằng dòng sau:
variable CS: std_logic_vector(1 downto 0); Carry và Sum
Trang 2310 Cho trước hệ tuần tự đồng bộ sau:
a) Lập bảng chuyển trạng thái của mạch trên
b) Viết mã VHDL cho câu a) có thêm tín hiệu reset_n tích cực thấp để cho chạy từ trạng
signal state: std_logic_vector( 1 downto 0);
signal state_X: std_logic_vector( 2 downto 0);
begin
state_X <= state & X;
Z <= '0' when state = "01" else '1';
Trang 25else
Next_state <= "10";
when "10" => if X = '0' then Next_state <= "00";
11 Thiết kế mạch phát hiện chuỗi bit vào nối tiếp có trị là "101" Viết mã VHDL với:
a) Dùng FSM loại Mealy với mô tả FSM
b) FSM loại Mealy dùng thanh ghi dịch chứa 3 bit liên tiếp và so sánh với "101"
Bài giải
a) FSM loại Mealy
Ta có được giản đồ trạng thái và bảng chuyển trạng thái như sau (kết quả lấy từ bài giảng thiết kế hệ tuần tự đồng bộ)
Trang 26Ta định nghĩa thêm kiểu mới cho các trạng thái không cần gán trạng thái mà CAD sẽ
else state <= S1; end if;
when others => null;
end case;
end if;
end process;
end bg;
Trang 27pattern <= pattern(1 downto 0) & X;
end if;
end process;
end bg;
12 Thiết kế mạch giải mã 3 sang 8 và mạch mã hóa ưu tiên 8 sang 3 (ưu tiên ngõ vào có trọng
số thấp nhất khi có nhiều bit vào là 1)
Trang 28architecture bg of Q12_1 is
signal CBA: std_logic_vector(0 to 2);
signal CBA_int: integer range 0 to 7;
Dạng sóng mô phỏng của mạch giải mã:
Dạng sóng mô phỏng của mạch mã hóa:
Trang 2913 Thiết kế bộ đếm lên 3 bit loại nối tiếp (còn gọi là bộ đếm gợn hay bất đồng bộ) với xung nhịp vào CLK (kích cạnh) Mạch có ngõ reset tích cực thấp reset_n Hãy viết mã VHDL
* Qo = level of Q before Clock pulse
All flipflops are positive-edge-triggered
signal D0, D1, D2, prn: std_logic;
signal Q2_int, Q1_int, Q0_int: std_logic;
begin
U1: DFF port map(D0, CLK, reset_n, prn, Q0_int);
U2: DFF port map(D1, D0, reset_n, prn, Q1_int);
U3: DFF port map(D2, D1, reset_n, prn, Q2_int);
prn <= '1';
D0 <= not Q0_int; D1 <= not Q1_int; D2 <= not Q2_int;
Q0 <= Q0_int; Q1 <= Q1_int; Q2 <= Q2_int;
end bg;
Trang 30elsif rising_edge(CLK) then
Q0_int <= not Q0_int;
elsif falling_edge(Q0_int) then
Q1_int <= not Q1_int;
elsif falling_edge(Q1_int) then
Q2_int <= not Q2_int;
end if;
end process;
Q0 <= Q0_int; Q1 <= Q1_int; Q2 <= Q2_int;
end bg;
Trang 31Chú ý: Ta có thể khai báo buffer cho các đối tượng ra Q2, Q1, và Q0, khi đó không cần dùng
các tín hiệu Q2_int, Q1_int, Q0_int
14 Thiết kế bộ đếm lên 3 bit loại song song (còn gọi là bộ đếm đồng bộ) với xung nhịp vào CLK (kích cạnh) Mạch có ngõ reset tích cực thấp reset_n Hãy viết mã VHDL với
a) Mô hình cấu trúc với component JKFF có sẵn
* Qo = level of Q before Clock pulse
All flipflops are positive-edge-triggered
signal J0, J1, J2, prn: std_logic;
begin
U1: JKFF port map(J0, J0, CLK, reset_n, prn, Q0);
U2: JKFF port map(J1, J1, CLK, reset_n, prn, Q1);
U3: JKFF port map(J2, J2, CLK, reset_n, prn, Q2);
prn <= '1'; J0 <= '1'; J1 <= Q0; J2 <= Q1 and Q0;
end bg;