Bài tập Kỹ thuật số về VHDL (AY1112-S1) - Hồ Trung Mỹ – Điện Tử - Khoa Điện - Điện Tử - ĐH Bách Khoa TP. HCM (có lời giải)
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
Bạn đang xem 20 trang mẫu của tài liệu "Bài tập Kỹ thuật số về VHDL (AY1112-S1) - Hồ Trung Mỹ – Điện Tử - Khoa Điện - Điện Tử - ĐH Bách Khoa TP. HCM (có lời giải)", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.
File đính kèm:
- bai_tap_ky_thuat_so_ve_vhdl_ay1112_s1_ho_trung_my_dien_tu_kh.pdf
Nội dung text: Bài tập Kỹ thuật số về VHDL (AY1112-S1) - Hồ Trung Mỹ – Điện Tử - Khoa Điện - Điện Tử - ĐH Bách Khoa TP. HCM (có lời giải)
- Loop IF A(i) = '1' then num := num+1; end if; end Loop; Transfer "num" Variable Value to a SIGNAL CASE num is WHEN 0 => C C C C <= "11"; 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 2
- WHEN "111" => C C 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 notgate; ARCHITECTURE Dataflow OF notgate IS BEGIN o <= NOT i; END Dataflow; 3-input NAND gate LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY nand3gate IS PORT( i1, i2, i3: IN STD_LOGIC; o: OUT STD_LOGIC); END nand3gate; ARCHITECTURE Dataflow OF nand3gate IS BEGIN o <= NOT(i1 AND i2 AND i3); END Dataflow; 4-input NAND gate LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY nand4gate IS Các BT giải sẵn về VHDL 2011 – trang 4
- END COMPONENT; COMPONENT or3gate PORT(I1, I2, I3: in STD_LOGIC; O: out STD_LOGIC); END COMPONENT; SIGNAL A1, A2, A3: STD_LOGIC; Declare Maj3 Local Signals begin Instantiate Gates g1: 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; USE IEEE.STD_LOGIC_1164.ALL; entity OPAR3 is PORT( X: in STD_LOGIC_VECTOR(2 downto 0); Z: out STD_LOGIC); end OPAR3; 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 6
- 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 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; entity MAJ3 is PORT( X: in STD_LOGIC_VECTOR(2 downto 0); Z: out STD_LOGIC); end MAJ3; architecture Structural_M of MAJ3 is COMPONENT and2 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); END COMPONENT; SIGNAL A1,A2,A3: STD_LOGIC; Declare Maj3 Local Signals begin Instantiate Gates 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 Các BT giải sẵn về VHDL 2011 – trang 8
- COMPONENT MAJ3 PORT( X: in STD_LOGIC_VECTOR(2 downto 0); Z: out STD_LOGIC); END COMPONENT; COMPONENT OPAR3 PORT( X: in STD_LOGIC_VECTOR(2 downto 0); Z: out STD_LOGIC); END COMPONENT; begin Instantiate Components c1: MAJ3 PORT MAP (A, C(1)); c2: OPAR3 PORT MAP (A, C(0)); end Structural; 2. Với mạch tổ hợp sau: Hãy viết mã VHDL với các cách sau (không thiết kế riêng mạch giải mã, mà chỉ cài đặt hàm F): 1) Lệnh đồng thời với phép gán dùng các toán tử logic 2) Lệnh đồng thời WHEN-ELSE 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 10
- 4) Lệnh tuần tự IF-THEN-ELSE signal assignment with IF-THEN-ELSE library ieee; 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 F F <= '0'; end case; end process; end a; Các BT giải sẵn về VHDL 2011 – trang 12
- 4. 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 CIRCUIT is port(A, B, C: in std_logic; S:in std_logic_vector (1 downto 0); Z: out std_logic); end CIRCUIT; architecture a of CIRCUIT is begin process(A, B, C, S) begin if (S(0)= ‘1’) then Z <= A; elsif (S(1) = ‘1’) then Z <= B; else Z <= C; end if; end process; end a; Các BT giải sẵn về VHDL 2011 – trang 14
- Bài giải. NX : Ngõ ra chỉ được cập nhật khi có cạnh lên tại CLK Đây là D F/F kích cạnh lên với ngõ vào là mạch tổ hợp như câu trên. 6. Ta cần thiết kế 1 mạch tổ hợp mà xuất phát từ thiết kế số thông thường, mạch này được ghép từ 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. Bài giải. Ta có thể dùng when-else hay with-select-when để mô tả các mạch này. a) Mã VHDL với 2 mạch độc lập library ieee; use ieee.std_logic_1164.all; entity Q06_1 is port( 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)); LED_7seg(0) = segment a 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 16
- "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) a) Dùng phương trình đặc tính của JK FF. 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 18
- 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; entity Q08_1 is generic (N: integer := 4); port( A, B: in std_logic_vector(N-1 downto 0); 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 : Các BT giải sẵn về VHDL 2011 – trang 20
- if N = 0 then FIN := '1'; Finished A + B = 10001 => C_out = 1 và Sum = 0001 Chú ý : Có 1 cách giải khác là tận dụng toán tử + (trong ieee.std_logic_unsigned.all) để tìm C và S : library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; . . . Thay dòng: variable S, C_in: std_logic; bằng dòng sau: variable CS: std_logic_vector(1 downto 0); Carry và Sum . . . Mã mới phần tính full adder như sau: if (FIN = '0') then CS := ('0' & CS(1)) + ('0' & A) + ('0' & B) ; Sum_int := CS(0) & Sum_int(Num_bits-1 downto 1); N := N - 1; if N = 0 then 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 22
- when "010" | "011" => state state state state state null; end case; end if; end process; end bg; Dạng sóng mô phỏng: Chú ý: Có nhiều cách viết khác để mô tả FSM, thí dụ sau đây là 1 cách viết khác: library ieee; use ieee.std_logic_1164.all; entity Q10_2 is port( X, CLK, reset_n: in std_logic; Z: out std_logic); end Q10_2; architecture bg of Q10_2 is signal Present_state: std_logic_vector( 1 downto 0); PS signal Next_state: std_logic_vector( 1 downto 0); NS begin Z <= '0' when Present_state = "01" else '1'; State_transition: process(CLK, reset_n) begin if (reset_n = '0') then Present_state <= "00"; elsif rising_edge(CLK) then Present_state <= Next_state ; end if; end process; Các BT giải sẵn về VHDL 2011 – trang 24
- Ta đị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ẽ tự gán trị cho nó. library ieee; use ieee.std_logic_1164.all; entity Q11_1 is port( X, CLK, reset_n: in std_logic; Z: out std_logic); end Q11_1; architecture bg of Q11_1 is type state_type is (S0, S1, S2); signal state: state_type; begin Z if X = '1' then state if X = '0' then state if X = '0' then state null; end case; end if; end process; end bg; Các BT giải sẵn về VHDL 2011 – trang 26
- architecture bg of Q12_1 is signal CBA: std_logic_vector(0 to 2); signal CBA_int: integer range 0 to 7; begin Decoder 3 to 8 CBA '0'); Y_int(CBA_int) := '1'; Y <= Y_int; end process; Priority Encoder 8 to 3 process(D_in) variable index_in: integer; begin for i in D_in'length -1 downto 0 loop if D_in(i) = '1' then index_in := i; end if; end loop; D_out <= conv_std_logic_vector(index_in,3); end process; end bg; 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: Các BT giải sẵn về VHDL 2011 – trang 28
- c) Các lệnh tuần tự: library ieee; use ieee.std_logic_1164.all; entity Q13_2 is port( CLK, reset_n: in std_logic; Q2, Q1, Q0: out std_logic); Q0: LSB end Q13_2; architecture bg of Q13_2 is signal Q2_int, Q1_int, Q0_int: std_logic; begin process(CLK, reset_n) begin if reset_n = '0' then Q0_int <= '0'; elsif rising_edge(CLK) then Q0_int <= not Q0_int; end if; end process; process(Q0_int) begin if reset_n = '0' then Q1_int <= '0'; elsif falling_edge(Q0_int) then Q1_int <= not Q1_int; end if; end process; process(Q1_int) begin if reset_n = '0' then Q2_int <= '0'; 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; Các BT giải sẵn về VHDL 2011 – trang 30
- b) Các lệnh tuần tự: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; De tinh cong so nhi phan voi so nguyen entity Q14_2 is port( CLK, reset_n: in std_logic; Q2, Q1, Q0: out std_logic); Q0: LSB end Q14_2; architecture bg of Q14_2 is signal Q: std_logic_vector(2 downto 0); begin process(CLK) begin if reset_n ='0' then Q <= "000"; elsif rising_edge(CLK) then Q <= Q + 1; end if; end process; Q2 <= Q(2); Q1 <= Q(1); Q0 <= Q(0); end bg; c) Với dãy đếm 1, 3, 5, 7, 1, . . Chỉ cần sửa lại trong phần process của b) như sau: if reset_n ='0' then Q <= "001"; elsif rising_edge(CLK) then if Q = "111" then Q <= "001"; else Q <= Q + 2; end if; end if; Các BT giải sẵn về VHDL 2011 – trang 32