Tải bản đầy đủ (.docx) (54 trang)

Điện tử viễn thông bài tập VHDL khotailieu

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.41 MB, 54 trang )

BÀI TẬP
THIẾT KẾ CÁC KHỐI MẠCH DÃY VÀ TỔ HỢP THÔNG
DỤNG
NHÓM 2:
1.Lê Thế Ưng.(các khối còn lại và tổng hợp)
2.Bùi Anh Tuấn.(mạch cộng tích lũy)
3.Hoàng Đức Anh.(Fsm)
4.Hoàng Ti Vi.(mạch cộng đơn giản)
5.Nguyễn Văn Tiến Lâm.(khối trừ)


I.CÁC KHỐI CƠ BẢN.
1.Khối cộng đơn giản
Khối cộng đơn giản: thực hiện phép cộng giữa hai số đƣợc biểu diễn dưới dạng
std_logic_vector hay bit_vector. Các cổng vào gồm hạng tử A, B, bit nhớ Cin,
các cổng ra bao gồm tổng Sum, và bit nhớ ra Cout:

Code của bộ cộng là:
--------- Bo cong don gian -------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------entity adder32 is
port(


Cin : in std_logic;
A : in std_logic_vector(31 downto 0);
B : in std_logic_vector(31 downto 0);
SUM : out std_logic_vector(31 downto 0);
Cout: out std_logic


);
end adder32;
architecture behavioral of adder32 is
signal A_temp : std_logic_vector(32 downto 0);
signal B_temp : std_logic_vector(32 downto 0);
signal Sum_temp : std_logic_vector(32 downto 0);
begin
A_temp <= '0'& A;
B_temp <= '0'& B;
sum_temp <= a_temp + b_temp + Cin;
SUM <= sum_temp(31 downto 0);
Cout <= sum_temp(32);
end behavioral;
- Sau khi mô phỏng ta được khối cộng như sau:


Code testbend của bộ cộng là:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-----------------------------------------entity test_add_32 is
end test_add_32;
-----------------------------------------architecture behavioral of test_add_32 is

signal Cin : std_logic := '0';
signal A : std_logic_vector(31 downto 0);
signal B : std_logic_vector(31 downto 0);
signal SUM : std_logic_vector(31 downto 0);
signal Cout : std_logic;

component adder32 is


port ( Cin : in std_logic;


A : in std_logic_vector(31 downto 0);
B

: in std_logic_vector(31 downto 0);

SUM : out std_logic_vector(31 downto 0);
Cout : out std_logic
);
end component;
begin
-- create test data
create_data: process
begin
A <= x"00001111";
B <= x"00000001";
wait for 150 ns;
A <= x"00000111";
B <= x"00000002";
wait for 170 ns;
A <= x"00000211";
B <= x"00000003";
wait for 70 ns;
A <= x"00000011";
B <= x"00000004";
wait;
end process create_data;



add: component adder32
port map (Cin, A, B, SUM, Cout);
end behavioral;
- Sau khi mô phỏng ta được:

Phân tích: ta có thể thấy được bộ cộng hoạt động chính xác.Ví dụ,tại thời điểm
268.2ns , đầu A được cấp giá trị là 273,đầu B được cấp giá trị 2 thì giá trị ra của sum
là 275.Tương tự với các khoảng thời gian khác thì bộ cộng vẫn hoạt động ổn định.
2.Khối trừ.
Do ngôn ngữ dùng trên máy tính là dạng nhị phân,vì vậy phép trừ cho 1 số được
xem là cộng với số bù 2 của số đó.Số bù 2 của 1 số thì bằng nghịch đảo của số
đó(dưới dạng nhị phân) cộng thêm 1.Ví dụ: A=10,đổi nhị phân = 01010 thì bù 2 của
A=10110.
A = 01010, Bù2(A) = not (A) + 1 = 10101 + 1 = 10110.
Dựa trên tính chất trên của số bù hai ta chỉ cần thực hiện một thay đổi nhỏ trong
cấu trúc của bộ cộng để nó có khả năng thực hiện cả phép cộng lẫn phép trừ mà
không làm thay đổi lớn về tài nguyên logic cũng như độ trễ của mạch. Tại đầu vào sẽ
bổ xung thêm tín hiệu SUB, tín hiệu này quyết định sẽ thực hiện phép cộng hay phép
trừ. Khi SUB = 1 để lấy bù 2 của B sẽ lấy đảo B và cho giá trị đầu vào Cin =1, để
hiện thực trên mạch cấu trúc bộ cộng đƣợc bổ xung một khối MUX trước cổng B,
khối này có hai đầu vào là B và not B, nếu SUB= 0 thì B được chọn, nếu SUB = 1
thì not B đƣợc chọn. Đầu vào Cin được OR với SUB trước khi vào bộ cộng.


Code của bộ trừ là:
------------ Bo cong trừ đơn giản ---------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;
-------------------------------------------entity adder_sub is
port(
SUB : in std_logic;
Cin : in std_logic;
A : in std_logic_vector(31 downto 0);
B : in std_logic_vector(31 downto 0);
SUM : out std_logic_vector(31 downto 0);
Cout: out std_logic
);
end adder_sub;
--------------------------------------------architecture rtl of adder_sub is
signal B_temp : std_logic_vector(31 downto 0);
signal Cin_temp : std_logic;
component adder32 is
port ( Cin : in std_logic;


A : in std_logic_vector(31 downto 0);
B : in std_logic_vector(31 downto 0);
SUM : out std_logic_vector(31 downto 0);
Cout : out std_logic
);
end component;
begin
Cin_temp <= SUB or Cin;
MUX32: process (B, SUB)
begin
if SUB = '1' then
B_temp <= not B;

else
B_temp <= B;
end if;
end process MUX32;
add: component adder32
port map (Cin_temp, A, B_temp, SUM, Cout);
end rtl;

3.thanh ghi
Thanh ghi là chuỗi các phần tử nhớ đƣợc ghép với nhau và là thành phần không
thể thiếu của các thiết kế mạch dãy, đặc điểm quan trọng nhất để phân biệt thanh ghi


với các khối tổ hợp là thanh ghi bao giờ cũng chịu sự điều khiển của xung nhịp đồng
bộ, giá trị đầu ra là giá trị lưu trong các ô nhớ của thanh ghi được gán bằng giá trị
của đầu vào tại các thời điểm nhất định (sườn dương hoặc sườn âm) theo điều khiển
xung nhịp đồng bộ, nếu so sánh với khối tổ hợp thì giá trị đầu ra của mạch tổ hợp
thay đổi tức thì ngay sau khi có sự thay đổi của các đầu vào.
Thường gặp và phổ biến nhất là các thanh ghi sử dụng D-flipflop và làm việc
đồng bộ theo sườn dương của xung nhịp hệ thống.
Code mô phỏng thanh ghi đơn giản:
-- Bo mon Vixuly KVTDT--- Simply register 32-bit --

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-----------------------------------------entity reg_32 is
port(
D : in std_logic_vector(31 downto 0);
Q : out std_logic_vector(31 downto 0);
CLK : in std_logic;

RESET : in std_logic
);
end reg_32;
architecture behavioral of reg_32 is
begin
reg_p: process (CLK)


begin
if CLK = '1' and CLK'event then
if RESET = '1' then
Q <= (others => '0');
else
Q <= D;
end if;
end if;
end process reg_p;

end behavioral;
-Sau khi mô phỏng ta được:

• Ta thấy có chân clock tạo xung,chân Data : chân dữ liệu, Q là giá trị đầu ra.Q
bằng D khi xung clk ở sườn dương.Tại các thời điểm khác Q có giá trị không
đổi.Chân reset tích cực 1,khi reset =1,Q trở lại bằng 0,reset=0 không có tác
dụng.
• Code testbend:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity test_reg_32 is
end test_reg_32;
architecture behavioral of test_reg_32 is
signal D: std_logic_vector(31 downto 0):= (others => '0');
signal Q: std_logic_vector(31 downto 0);
signal CLK: std_logic := '0';
signal RESET: std_logic := '0';
component reg_32 is
port ( D : in std_logic_vector(31 downto 0);
Q : out std_logic_vector(31 downto 0);
CLK : in std_logic;
RESET: in std_logic
);
end component;
begin
--create clock
create_clock: process
begin
wait for 15 ns;
CLK <= not CLK after 50 ns;
end process create_clock;


create_data: process
begin
RESET <= '0';
D <= x"a0001111";
wait for 10 ns;
RESET <= '1';
wait for 100 ns;

RESET <= '0';
wait for 150 ns;
D <= x"b0011111";

wait for 170 ns;
D <= x"c0111111";
wait for 70 ns;
D <= x"d1111111";
wait;
end process create_data;
reg32: component reg_32 port map (D, Q, CLK, RESET);
end behavioral;

- Kết quả :


-Ta thấy: khi reset = 1 ,clock sườn dương,mặc dù data=2684358929 thì Q vẫn
chỉ bằng 0.
Khi reset=0,clock ở sườn dương(t=180ns) thì Q mang giá trị bằng
data.Và chỉ khi clock tại sườn dương thì Q mới cập nhật giá trị mới theo giá
trị của data,còn ở sườn âm thì dù data có cập nhật thì Q cũng không đổi.
4.Bộ cộng tích lũy
Bộ cộng tích lũy là sự kết hợp giữa bộ cộng và thanh ghi . Đầu ra của bộ cộng
đƣợc nối với đầu vào của thanh ghi, còn đầu ra của thanh ghi được dẫn vào
cổng B của bộ cộng, sau mỗi xung nhịp đồng hồ giá trị này được cộng thêm
giá trị ở cổng A và lưu lại vào thanh ghi.
Code mô phỏng cấu trúc
------------accumullator----------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------entity accumulator_32 is
port(
A : in std_logic_vector(31 downto 0);
Q : buffer std_logic_vector(31 downto 0);


CLK : in std_logic;
RESET : in std_logic
);
end accumulator_32;
architecture structure of accumulator_32 is
signal sum32 : std_logic_vector(31 downto 0);
signal Q_sig : std_logic_vector(31 downto 0);
signal Cout : std_logic;
signal Cin : std_logic;

----COMPONENT ADD_32---component adder32 is

port (
Cin: std_logic;
A : in std_logic_vector(31 downto 0);
B : in std_logic_vector(31 downto 0);
SUM : out std_logic_vector(31 downto 0);
Cout: out std_logic
);
end component;

----COMPONENT REG_32----



component reg_32 is
port ( D : in std_logic_vector(31 downto 0);
Q : out std_logic_vector(31 downto 0);
CLK : in std_logic;
RESET: in std_logic
);
end component;

begin
Q_sig <= Q;
Cin <= '0';
add32: component adder32
port map (Cin, A, Q_sig, sum32, Cout);
reg32: component reg_32
port map (sum32, Q, CLK, RESET);

end structure;

-Sau khi mô phỏng ta có:


Code testbend của bộ:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------entity accumulator_32_test is
end accumulator_32_test;
----------------------------------------architecture behavioral of accumulator_32_test is


signal A

: std_logic_vector(31 downto 0);

signal Q

: std_logic_vector(31 downto 0);

signal CLK : std_logic := '0';
signal RESET : std_logic;
----COMPONENT ADD_32---component accumulator_32 is


port ( A
Q

: in std_logic_vector(31 downto 0);
: buffer std_logic_vector(31 downto 0);

CLK : in std_logic;
RESET : in std_logic
);
end component;
begin
--create clock
create_clock: process
begin
wait for 15 ns;
CLK <= not CLK after 50 ns;

end process create_clock;
-- create input data
create_data: process
begin
RESET <= '0';
A

<= x"00000011";

wait for 10 ns;
RESET <= '1';
wait for 150 ns;
RESET <= '0';
wait;


end process create_data;
acc32: component accumulator_32
port map (A, Q, CLK, RESET);
end behavioral;
- Kết quả:

Ta thấy: Sau mỗi xung clock sườn dương thì bộ cộng thêm 17(khi reset =0).Khi
reset =1 giá trị được trở về 0.
5.Bộ đếm
Bộ đếm là một trường hợp đặc biệt của bộ cộng tích lũy, nếu ta cho đầu vào của
bộ cộng A luôn nhận giá trịbằng 1 thì sau mỗi xung nhịp giá trị trong thanh ghi tăng
thêm 1. Trong trường hợp đếm ngược thì cho giá trị của A bằng -1. Giá trị đếm là
giá trị lưu trong thanh ghi còn xung đếm chính là xung nhịp hệ thống.
Code mô tả bộ đếm:

-------------------library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity counter4_test is
end entity;

architecture behavioral of counter4_test is
signal count4 : std_logic_vector( 3 downto 0);
signal count4_set : std_logic_vector( 3 downto 0);
signal enable : std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
signal clk

: std_logic:= '0'; -- Dau vao xung nhip Input clock

signal reset : std_logic; -- tin hieu reset cho bo dem

component counter4_set is
port (
count :out std_logic_vector( 3 downto 0); -- giá tri bo dem
enable :in std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
clk

:in std_logic; -- Dau vao xung nhip Input clock

reset :in std_logic -- tin hieu reset cho bo dem

);
end component;

component counter4 is
port (


count :out std_logic_vector( 3 downto 0); -- giá tri bo dem
enable :in std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
clk

:in std_logic; -- Dau vao xung nhip Input clock

reset :in std_logic -- tin hieu reset cho bo dem
);
end component;

begin
--create clock
create_clock: process
begin
wait for 15 ns;
CLK <= not CLK after 20 ns;
end process create_clock;
-- create input data
create_data: process
begin
reset <= '0'; enable <= '1';
wait for 120 ns;

reset <= '1';


wait for 50 ns;
reset <= '0';
wait for 100 ns;
enable <= '0';
wait for 100 ns;
enable <= '1';
wait;
end process create_data;

-- installation of 4 bit counter
u1: counter4_set port map (count4_set, enable, clk, reset);
u2: counter4 port map (count4, enable, clk, reset);
end architecture behavioral;
Kết quả :


Bộ đếm trên ở chế độ đếm sẽ đếm nhịphân với Kđ = 2^i, các giá trị đếm thay
đổi từ từ 0 đến 15 sau đó lại bắt đầu đếm từ 0, trong trường hợp muốn đặt Kd bằng
một giá trị khác cần thêm một khối tổ hợp làm nhiệm vụso sánh giá trị đếm với Kd
để đặt lại giá trị đếm như ở mô tả dưới đây, bộ đếm với Kd= 10:
-------------------library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter4_set is
port (

count :out std_logic_vector( 3 downto 0); -- giá tri bo dem
enable :in std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
clk

:in std_logic; -- Dau vao xung nhip Input clock

reset :in std_logic -- tin hieu reset cho bo dem
);
end entity;

architecture rtl of counter4_set is
signal cnt :std_logic_vector ( 3 downto 0) := "0000";
begin
process (clk, reset) begin


if (reset = '1') then
cnt <= "0000";
elsif (rising_edge(clk)) then
if (enable = '1') then
if cnt = "1010" then -- neu gia tri dem bang 10 thi reset
cnt <= "0000";
else
cnt <= cnt + 1;
end if;
end if;
end if;
end process;
count <= cnt;

end architecture;
Kết quả :


Code testband cho cả 2 bộ đếm :
-------------------library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter4_test is
end entity;

architecture behavioral of counter4_test is
signal count4 : std_logic_vector( 3 downto 0);
signal count4_set : std_logic_vector( 3 downto 0);


signal enable : std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
signal clk

: std_logic:= '0'; -- Dau vao xung nhip Input clock

signal reset : std_logic; -- tin hieu reset cho bo dem

component counter4_set is
port (
count :out std_logic_vector( 3 downto 0); -- giá tri bo dem
enable :in std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu

nguyen
clk

:in std_logic; -- Dau vao xung nhip Input clock

reset :in std_logic -- tin hieu reset cho bo dem
);
end component;

component counter4 is
port (
count :out std_logic_vector( 3 downto 0); -- giá tri bo dem
enable :in std_logic; -- cho phep dem, neu enable =1 dem, neu khong giu
nguyen
clk

:in std_logic; -- Dau vao xung nhip Input clock

reset :in std_logic -- tin hieu reset cho bo dem
);
end component;


×