You are on page 1of 10

Khoa Vô tuyến điện tử

Bộ môn Kỹ thuật Xung, số, VXL

Thực hành: Thiết kế logic số

Bài 04: Khối mạch dãy phức tạp – bộ cộng


bit nối tiếp dùng 1 FA (serial-bit adder)

Mục đích:
Viết mô tả và kiểm tra cho khối mạch dãy phức tạp là khối cộng 8
bít dùng một duy nhất 1 full_adder. Khối mạch cấu trúc từ bộ đếm, thanh
ghi dịch một bit nối tiếp và một full_adder. Kỹ năng chính cần thực hiện
ở bài này là cách thức ghép nối các khối đơn giản để tạo thành khối
mạch phức tạp và kiểm tra hoạt động của khối mạch dãy.
Công cụ phục vụ thực hành : Máy vi tính
Thời gian : 1h30
1. Khối cộng bit nối tiếp (Serial – bit adder)
reset, clk

A
reset
shifter_reg.vhd
counter.vhd
‘0' WE cnt_reset
Din
temp= cnt=”111"
bitin SHIFTER_REGA COUNTER CNT
Dout
cnt_enable

REG
Shift_enable
WE
B RESULT
shifter_reg.vhd reg_temp

Din
bitin SHIFTER_REGB Dout

WE Shift_enable shift_enable

B A
Cout
bitCout CO FA CINCIN
X”00"
S
full_adder.vhd

Din Shift_enable
MUX

CIN bitcin REG_CIN reg_in


SUM
bitSum bitin SHIFTER_REGB Dout
mux1.vhd
WE

shifter_reg.vhd
WE
reg.vhd
shifter.vhd
mux.vhd

Sơ đồ tổng quát của khối cộng bit nối tiếp thể hiện trên hình vẽ. Phép
cộng được thực hiện bằng cách sử dụng các thanh ghi dịch ở đầu vào để đẩy
dần các bit Ai, Bi tương ứng vào một bộ Full_adder và thực hiện cộng từng bit,
kết quả từ full_adder được đẩy dần ra 1 thanh ghi lưu kết quả. Bộ cộng N bit
sau N xung nhịp sẽ cho ra kết quả.
Bước 1: Chuẩn bị các mã nguồn có sẵn:
Trong sơ đồ trên cho phép sử dụng các mã nguồn có sẵn bao gồm:
1-Khối full_adder được mô tả trong tệp full_adder.vhd
-----------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-----------------------------------------
entity full_adder is
port (A : in std_logic;
B : in std_logic;
Cin : in std_logic;
S : out std_logic;
Cout : out std_logic
);
end full_adder;
----------------------------------------
architecture dataflow of full_adder is
begin
S <= A xor B xor Cin;
Cout <= (A and B) or (Cin and (a or b));
end dataflow;
----------------------------------------
1-Khối chọn kênh MUX được mô tả trong tệp mux.vhd
----------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
----------------------------------------------
entity mux is
port(
Sel : in std_logic;
Din1 : in std_logic_vector(7 downto 0);
Din2 : in std_logic_vector(7 downto 0);
Dout : out std_logic_vector(7 downto 0)
);
end mux;
-----------------------------------------------
architecture rtl of mux is
begin
selm: process (Sel, Din1, Din2)
begin
if Sel = '1' then
Dout <= Din1;
else
Dout <= Din2;
end if;
end process selm;

end rtl;
-----------------------------------------------

1-Khối shifter được mô tả trong tệp shifter.vhd


--------------------------------------------------------
library ieee;
use IEEE.STD_LOGIC_1164.ALL;
--------------------------------------------------------
entity shifter is
port (
bitin : in std_logic;
shift_enable : in std_logic;
shift_in : in std_logic_vector(7 downto 0);
shift_out : out std_logic_vector(7 downto 0)
);
end entity;
--------------------------------------------------------
architecture rtl of shifter is

begin
shifting: process (bitin, shift_enable, shift_in)
begin
if shift_enable = '1' then
shift_out <= bitin & shift_in(7 downto 1);
end if;
end process shifting;

end architecture;
--------------------------------------------------------
Khối này thực hiện dịch sang bên phải 1 bit và vị trí bít trống bị dịch đi sẽ được
lưu giá trị ở đầu vào bitin
1-Khối thanh ghi được mô tả trong tệp reg.vhd
-----------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-----------------------------------------
entity reg is
port(
D : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
CLK : in std_logic;
RESET : in std_logic
);
end reg;
------------------------------------------
architecture behavioral of reg is
begin
reg_p: process (CLK, RESET)
begin
if RESET = '1' then
Q <= (others => '0');
elsif CLK = '1' and CLK'event then
Q <= D;
end if;
end process reg_p;
end behavioral;
------------------------------------------

Sinh viên có thể sao chép hoặc tạo các mã nguồn có sẵn trên vào trong
một thư mục trong D:/student/name/ để bắt đầu làm việc.
Bước 2: Biên dịch toàn bộ các file đã tạo ở bước 1.
Hướng dẫn: Vì đây là một bài có nhiều mã nguồn nên ở bước này ta sẽ tạo một
file script có tên run.do để phục vụ biên dịch mô phỏng cho cả quá trình. Nội
dung file ở bước này tạm thời như sau, ở các bước sau ta sẽ bổ xung thêm các
lệnh vào script này.
quit -sim
vlib work
vcom counter.vhd
vcom full_adder.vhd
vcom mux.vhd
vcom reg.vhd
vcom shifter.vhd
Sau khi tạo xong file này lưu vào trong thư mục làm việc chứa mã nguồn và
thực hiện chạy script cho biên dịch bằng lệnh
do run.do
Bước 3: Viết mô tả khối thanh ghi dịch dựa trên các khối có sẵn.

Hướng dẫn: Thanh ghi dịch này khác với thanh ghi dịch ở bài thí nghiệm trước. phép
dịch luôn dịch sang bên phải 1 bit và bit trống được điền giá trị từ bên ngoài vào từ
cổng bitin. Cổng shift_enable là cổng cho phép dịch hoặc không dịch.

REG

bitin REG

clk, reset WE Din bitin shift_enable

Shift_in

SHIFTER

shifter.vhd
shift_out

MUX
mux.vhd
mux_out

REG1

reg.vhd

Dout

Sơ đồ của khối dịch như ở hình trên, mã nguồn của thanh ghi dịch nối tiếp
được liệt kê ở dưới đây. Đây là một ví dụ về cách ghép nối các khối con để tạo
thành thiết kế lớn hơn. Các bước cài đặt khối con làm tương tự như khi viết khối
kiểm tra nhanh (cài đặt DUT). Trong trường hợp này khối của chúng ta có nhiều khối
con hơn.

Đầu tiên trong phần khai báo kiến trúc khai báo các component sẽ sử dụng
trong hình ví dụ cho khối reg:

component reg is
port(
D : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
CLK : in std_logic;
RESET : in std_logic
);
end component;
Sau đó cũng trong phần khai báo kiến trúc cần khai báo tất cả các tín
hiệu bên trong, tín hiệu bên trong là tín hiệu kết nối giữa các khối của thiết kế,
ví dụ:
signal shift_out: std_logic_vector(7 downto 0);
signal reg_in: std_logic_vector(7 downto 0);
Cuối cùng là cài đặt các khối con tương ứng với các tín hiệu trên hình,
phần này viết trực tiếp trong phần mô tả kiên trúc, ví dụ:
sh1 : component shifter
port map (bitin => bitin,
shift_enable => shift_enable, shift_in => shift_in,
shift_out => shift_out);
mux1: component mux
port map (Sel => WE, Din1 => Din,
Din2 => shift_out, Dout => reg_in);
Trong ví dụ trên sh1, mux1 là các tên gọi của các khối cài đặt và có thể
bất kz, tránh trùng với các tên khác đã dùng.
Bước 4: Viết mô tả cho bộ đếm.

Hướng dẫn: Mục đích của bộ đếm ở đây là để đếm số lần dịch, vì có 8 bit cộng
nên ta sẽ viết một bộ đếm đến 8.
Các cổng của bột đếm như ở hình vẽ sau:
CNT

Clk, reset COUNTER

Cnt_enable

Trong đó cổng cnt_enable là cổng cho phép đếm, khi cnt_enable = 1 thì
bộ đếm làm việc bình thường, khi cnt_enable = 0 thì bộ đếm dừng lại và giữ
nguyên giá trị đếm. Cổng clk chính là cổng xung đếm, cổng reset là cổng không
đồng bộ, cổng cnt là giá trị hiện tại của bộ đếm.
Bản chất của bộ đếm là một bộ cộng tích lũy đặc biệt với giá trị tích lũy
bằng 1, thường được mô tả như sau:
if reset = '1' then
temp_cnt <= (others =>'0');
elsif rising_edge(clk) then
if counter_enable = '1' then
temp_cnt <= temp_cnt + 1;
end if;
end if;
Bước 5: Mô tả khối cộng nối tiếp.
reset, clk

A
reset
shifter_reg.vhd
counter.vhd
‘0' WE cnt_reset
Din
temp= cnt=”111"
bitin SHIFTER_REGA COUNTER CNT
Dout
cnt_enable
REG

Shift_enable
WE
B RESULT
shifter_reg.vhd reg_temp

Din
bitin SHIFTER_REGB Dout

WE Shift_enable shift_enable

B A
Cout
bitCout CO FA CINCIN
X”00"
S
full_adder.vhd

Din Shift_enable
MUX

CIN bitcin REG_CIN reg_in


SUM
bitSum bitin SHIFTER_REGB Dout
mux1.vhd
WE

shifter_reg.vhd
WE
reg.vhd
shifter.vhd
mux.vhd
Các thành phần của khối cộng đã đầy đủ bao gồm thanh ghi dịch nối tiếp
(shifter_reg.vhd), khối chọn kênh 1 bit (mux1.vhd), khối đếm (counter.vhd). khối FA
(full_adder.vhd).

Các cổng vào ra của khối trên bao gồm cổng A, B 8-bit là các hạng tử, Cin là
bit nhớ đầu vào, Sum là kết quả cộng , Cout là bít nhớ ra. Các tín hiệu toàn cục là
CLK và RESET, ngoài ra cổng WE là tín hiệu khi tích cực WE = 1 cho biết là dữ liệu
ở các đầu vào A, B đang được nạp vào các thanh ghi SHIFTER_REGA,
SHIFTER_REGB để thực hiện cộng. Tín hiệu ra RESULT = 1 cho biết giá trị SUM và
Cout đã đúng.

- Thanh ghi dịch SHIFTER_REGA, SHIFTER_REGB:


Các thanh ghi sẽ dịch sang bên phải một bit nếu như không phải thời
điểm có kết quả ra, ở thời điểm này bộ đếm đã đếm xong 8 xung nhịp do vậy
các tín hiệu này được mô tả như sau:
Tín hiệu temp báo hiệu cnt đã đếm đến “111”
with cnt select
temp <= '1' when "111",
'0' when others;
Tín hiệu này được làm trễ một xung nhịp bằng một một D-flip-flop như
mô tả sau:
reg_p: process (CLK)
begin
if CLK = '1' and CLK'event then
temp_reg <= temp;
end if;
end process reg_p;
Cuối cùng tín hiệu shift_enable là đảo của temp đã bị làm trễ.
shift_enable <= not temp_reg;
Tín hiệu bitin của hai thanh ghi dịch SHIFTER_REGA, SHIFTER_REGB
không quan trọng và gán bằng hằng số bất kz, trên hình ta gán bằng ‘0’.
Tín hiệu vào song song của thanh ghi SHIFTER_REGA, SHIFTER_REGB lấy
lần lượt từ các cổng A, B 8 bit, cổng WE của các thanh ghi lấy từ cổng WE của
khối serial_bit_adder.
- Bộ đếm COUNTER.
Tín hiệu counter_enable chính là tín hiệu shift_enable cho các thanh ghi
SHIFTER_REGA, SHIFTER_REGB.
counter_enable <= shift_enable;
Bộ đếm reset nếu bắt đầu nạp dữ liệu để thực hiện phép toán (WE =1 )
hoặc khi có reset không đồng bộ của toàn khối.
cnt_reset <= WE or reset;
- Khối Full_Adder

Các tín hiệu bên trong bitA, bitB chính là các bit thấp nhất của hai thanh ghi
dịch SHIFTER_REGA, SHIFTER_REGB, các bit này được đưa vào khối FA.

bitA <= regA(0);


bitB <= regB(0);
Trong đó regA, regB chính là các giá trị của các thanh ghi dịch tương ứng
cổng Dout.
Để mô tả chuỗi bit nhớ cần có một khối chọn kênh một bit với các đầu vào là
bitCout, và Cin, tín hiệu chọn kênh là WE, nếu như tại thời điểm đầu tiên(WE = 1) thì
đầu ra reg_cin = Cin, còn tại các thời điểm khác đầu vào bit nhớ chính là giá trị
đầu ra bit nhớ lần trước nên Reg_cin = bitCout.

Tín hiệu bitCin vào cổng CIN của khối full_adder chính là reg_cin được
làm trễ một xung nhịp vad được mô tả như sau:

if CLK = '1' and CLK'event then


bit_Cin <= Reg_cin;
end if;
Thanh ghi SHIFTER_SUM
Tín hiệu bitSum là đầu ra của Full_Adder đóng vai trò là đầu vào cho
thanh ghi SHIFTER_SUM.
Tín hiệu RESULT bằng 1 nếu như kết quả đã xuất hiện ở cổng ra SUM và
Cout kết quả chính xác có sau 8 xung nhịp cho bộ cộng 8 bit, do dó RESULT
trùng với tín hiệu temp_reg đã trình bày ở trên.
--tin hieu result tre nhip hon temp 1 xung nhip
RESULT <= temp_reg;
Cổng vào dữ liệu song song của thanh ghi REG_SUM không quan trọng,
có thể gán bằng giá trị bất kz 8 bit, ở trên hình ta gán bằng giá trị của x”00”.
Cổng vào WE của thanh ghi này cũng không quan trọng, ta lấy luôn tín hiệu
WE.
Bước 6: Kiểm tra khối thiết kế:
Hướng dẫn: Để kiểm tra khối thiết kế thì cách thức không khác gì với những bài
đã làm trước đây. Quan trọng nhất là phải tạo được tín hiệu xung clk:
--create clock
create_clock: process
begin
wait for 2 ns;
CLK <= not CLK after 50 ns;
end process create_clock;
Sau đó là tạo tín hiệu điều khiển hợp lý gồm reset và WE, ví dụ như sau
A <= x"1B"; B <= x"0c"; Cin <= '0';
reset <= '0'; WE <= '0';
wait for 150 ns;
reset <= '1';
wait for 170 ns;
reset <= '0';
WE <= '1';
wait for 150 ns;
WE <= '0';
wait;
Kết quả mô phỏng có dạng như sau:

You might also like