Các BT giải sẵn về VHDL 2011 – 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:
a) Dùng mô hình hành vi
b) Dùng mô hình luồng dữ liệu
c) Lệnh case-when
d) Dùng mô hình cấu trúc
Bài giải.
Với yêu cầu của đề bài, ta có được bảng chân trị sau:
Ngõ vào Ngõ ra
A2 A1 A0 C1 C0
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1
Phần đầu dùng thư viện IEEE và khai báo entity thì giống nhau cho các cách:
TD: Với khai báo của cách 1:
library ieee;
end CASE;
end process;
end Algorithmic;
Dạng sóng mô phỏng hoạt động:
Chú ý:
Có cách giải khác trong thí dụ của MaxplusII:
MAX+plus II VHDL Example
Combinatorial Process Statement
Copyright (c) 1994 Altera Corporation
ENTITY proc IS
PORT
(
d : IN BIT_VECTOR (2 DOWNTO 0);
q : OUT INTEGER RANGE 0 TO 3
);
END proc;
ARCHITECTURE maxpld OF proc IS
BEGIN
count the number of bits with the value 1 in word d
PROCESS (d)
VARIABLE num_bits : INTEGER;
BEGIN
Các BT giải sẵn về VHDL 2011 – trang 3
num_bits := 0;
FOR i IN d'RANGE LOOP
WHEN "001" => C <= "01";
WHEN "010" => C <= "01";
WHEN "011" => C <= "10";
WHEN "100" => C <= "01";
WHEN "101" => C <= "10";
WHEN "110" => C <= "10";
Các BT giải sẵn về VHDL 2011 – trang 4
WHEN "111" => C <= "11";
WHEN OTHERS => C <="ZZ";
end CASE;
end process;
end Truth_Table;
d) Dùng mô hình cấu trúc
Có 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:
NOT gate
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY notgate IS PORT(
i: IN STD_LOGIC;
o: OUT STD_LOGIC);
END Dataflow;
2-input AND gate
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY and2gate IS
PORT(
i1, i2: IN STD_LOGIC;
o: OUT STD_LOGIC);
END and2gate;
ARCHITECTURE Dataflow OF and2gate IS
BEGIN
o <= i1 AND i2;
END Dataflow;
3-input OR gate
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY or3gate IS
PORT(
i1, i2, i3: IN STD_LOGIC;
o: OUT STD_LOGIC);
END or3gate;
ARCHITECTURE Dataflow OF or3gate IS
BEGIN
o <= i1 OR i2 OR i3;
END Dataflow;
Majority of 3 bit number
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
architecture Structural_O of OPAR3 is
COMPONENT notgate
PORT( i: in STD_LOGIC;
O: out STD_LOGIC);
END COMPONENT;
COMPONENT nand3gate
PORT( I1, I2, I3: in STD_LOGIC;
O: out STD_LOGIC);
END COMPONENT;
COMPONENT nand4gate
PORT( I1, I2, I3, I4: in STD_LOGIC;
O: out STD_LOGIC);
END COMPONENT;
SIGNAL A1B, A2B, A0B, Z1, Z2, Z3, Z4: STD_LOGIC;
begin
Instantiate Gates
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);
Các BT giải sẵn về VHDL 2011 – trang 7
g8: nand4gate PORT MAP (Z1, Z2, Z3, Z4, Z);
end Structural_O;
ONES_CNT_EX4: Main Circuit
LIBRARY IEEE;
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;
Các BT giải sẵn về VHDL 2011 – trang 8
2) 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
Z: out STD_LOGIC);
end OPAR3;
architecture Structural_O of OPAR3 is
COMPONENT a_not
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);
END COMPONENT;
SIGNAL A1B, A2B, A0B, Z1, Z2, Z3, Z4: STD_LOGIC;
begin
Instantiate Gates
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);
end Structural_O;
ONES_CNT_EX4: Main Circuit
3) Lệnh đồng thời WITH-SELECT-WHEN
4) Lệnh tuần tự IF-THEN-ELSE
5) Lệnh tuần tự CASE-WHEN
Bài giải.
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);
end Q02_1;
architecture a of Q02_1 is
signal D1, D5, D7: std_logic;
begin
D1 <= not(A) and not(B) and C;
Các BT giải sẵn về VHDL 2011 – trang 11
D5 <= A and not(B) and C;
D7 <= A and B and C;
F <= D1 or D5 or D7;
end a; 2) Lệnh đồng thời WHEN-ELSE
signal assignment with WHEN-ELSE
library ieee;
use ieee.std_logic_1164.all;
entity Q02_2 is
port( A, B, C: in std_logic; C: LSB
F: out std_logic);
use ieee.std_logic_1164.all;
entity Q02_4 is
port( A, B, C: in std_logic; C: LSB
F: out std_logic);
end Q02_4;
architecture a of Q02_4 is
signal ABC: std_logic_vector(2 downto 0);
begin
ABC <= A&B&C;
process(ABC)
begin
if (ABC= "001" or ABC = "101" or ABC ="111")
then
F <= '1';
else
F <= '0';
end if;
end process;
end a;
5) Lệnh tuần tự CASE-WHEN
signal assignment with CASE-WHEN
library ieee;
use ieee.std_logic_1164.all;
entity Q02_5 is
port( A, B, C: in std_logic; C: LSB
F: out std_logic);
end Q02_5;
architecture a of Q02_5 is
signal ABC: std_logic_vector(2 downto 0);
cout <= (a and s4) or ( s4 and cin) or (a and cin);
U1: process(inst)
begin
case(inst(2 downto 1)) is
when "00" => F <= s0;
when "01" => F <= s1;
when "10" => F <= s2;
when others => F <= s3;
end case;
end process;
U2: process(inst)
begin
if (inst(0) = '0') then
s4 <= b;
else
s4 <= not b;
end if;
end process;
end bg;
Bài giải.
Ta thấy 2 phép gán sau :
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)
Các BT giải sẵn về VHDL 2011 – trang 14
else
F <= Z ;
end if ;
F = C1.X + C1’(C2.Y + C2’.Z)
F = C1.X + C1’C2.Y + C1’ C2’.Z
Với C1 = cond1 và C2 = cond2
Á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:
entity CIRCUIT is
port (A, B, S1, S2, S3, CLK: in std_logic;
Y: out std_logic);
end CIRCUIT;
architecture a of CIRCUIT is
begin
process(CLK)
begin
if (CLK'event and CLK='1') then
if (A='1') then
Y <= S3;
elsif (B = '0') then
Y <= S2;
else
end Q06_1;
architecture bg of Q06_1 is
signal s_BCD : std_logic_vector (3 downto 0);
begin
Priority Encoder
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
Các BT giải sẵn về VHDL 2011 – trang 17
BCD to 7 segment Decoder: LED_7seg = gfedcba
LED_7seg <= "0111111" when s_BCD = "0000" else
"0000110" when s_BCD = "0001" else
"1011011" when s_BCD = "0010" else
"1001111" when s_BCD = "0011" else
"1100110" when s_BCD = "0100" else
"1101101" when s_BCD = "0101" else
"1111101" when s_BCD = "0110" else
"0000111" when s_BCD = "0111" else
"0000000" when s_BCD = "1000" else
"1101111" when s_BCD = "1001" else
(others => '0');
b) Dùng bảng hoạt động của JK FF.
c) Nếu muốn Preset PR đồng bộ thì phải sửa lại như thế nào?
Bài giải.
a) Dùng phương trình đặc tính của JK FF:
library ieee;
use ieee.std_logic_1164.all;
entity JK_FF is port(
J, K, CLK, PR, CLR: in std_logic;
PR, CLR: Asynchronous Preset and Clear
Q, Q_n: out std_logic);
end JK_FF;
architecture bg of JK_FF is
signal Q_int: std_logic;
begin
process(CLK, PR, CLR)
begin
if (CLR = '1') then
Q_int <= '0';
elsif (PR = '1') then
Q_int <= '1';
elsif rising_edge(CLK) then
Q_int <= (J and not Q_int) or (not K and Q_int);
end if;
end process;
Q <= Q_int;
Q_n <= not Q_int;
end bg;
Dạng sóng mô phỏng:
Các BT giải sẵn về VHDL 2011 – trang 19
end bg;
c) Ta chỉ cần viết lại như sau :
if (CLR = '1') then
Q_int <= '0';
elsif rising_edge(CLK) then
if (PR = '1') then
Q_int <= '1';
else
Phần mã gán Q_int
end if ;
end if ;
Các BT giải sẵn về VHDL 2011 – trang 20
Dạ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?
Bài giải.
a) Khi sử dụng toán tử cộng/trừ thì ta phải dùng gói ieee.std_logic_unsigned.all :
Parallel Adder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
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.
Bài giải.
library ieee;
use ieee.std_logic_1164.all;
entity Q09_1 is
generic (Num_bits: integer := 4);
port(
A, B, Start, CLK: in std_logic;
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);
begin
if (Start = '1') then
FIN := '0';
N := Num_bits;
C_in := '0';
Finished <= '0';
elsif (CLK'event and CLK = '0') then and FIN = '0')
if (FIN = '0') then
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);
FIN := '1';
Finished <= '1';
Sum <= Sum_int;
C_out <= CS(1);
end if;
end if;
Các BT giải sẵn về VHDL 2011 – trang 23
10. 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
thái Q
1
Q
2
=00.
Bài giải.
a) Từ sơ đồ mạch ta có thể tìm được các phương trình đặc tính cho các FF và ngõ ra Z :
D
1
= Q
1
+
= Q
1
’ + Q
2
; D
2
= Q
library ieee;
use ieee.std_logic_1164.all;
entity Q10_1 is
port( X, CLK, reset_n: in std_logic;
Z: out std_logic);
end Q10_1;
architecture bg of Q10_1 is
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';
process(CLK, reset_n)
begin
if (reset_n = '0') then
state <= "00";
elsif rising_edge(CLK) then
case state_X is
when "000" => state <= "10";
when "001" => state <= "01";
Các BT giải sẵn về VHDL 2011 – trang 24
when "010" | "011" => state <= "10";
when "110" => state <= "00";
when "111" => state <= "10";
when "100" => state <= "00";
when "101" => state <= "01";
when others => null;
end case;
end if;
end process;
Find_Next_state:
process(Present_state)
begin
case Present_state is
when "00" => if X = '0' then
Next_state <= "10";
else
Next_state <= "01";
end if;
when "01" => Next_state <= "10";
when "11" => if X = '0' then
Next_state <= "00";
else
Next_state <= "10";
end if;
when "10" => if X = '0' then
Next_state <= "00";
else
Next_state <= "01";
end if;
when others => null;
end case;
end process;
end bg;
Dạng sóng mô phỏng: 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: