Chương 7: Signal và Variable
END PROCESS; END ok;
END ok;
Một lỗi thường xuyờn khi sử dụng SIGNAL là khụng nhớ nú cú thể yờu cầu một khoảng thời gian để cập nhật. Do đú, phộp gỏn sel <= sel + 1 (dũng 16) trong cỏch 1, kết quả cộng thờm 1 bất kể giỏ trị vừa được tạo liền trước cho sel, với phộp gỏn sel <= 0 (dũng 15) cú thể khụng cú thời gian để tạo. Điều này đỳng với với sel <= sel +2 (dũng 18). Đõy khụng là vấn đề khi sử dụng VARIABLE, phộp gỏn của nú luụn tức thỡ.
Khớa cạnh thứ 2 cú thể là một vấn đề trong cỏch 1 là hơn một phộp toỏn đang được tạo cho cựng SIGNAL (sel, dũng 15, 16, và 18), cú thể khụng được chấp nhận. Túm lại, chỉ một phộp gỏn với SIGNAL được phộp bờn trong PROCESS, vỡ vậy phần mềm chỉ xột phộp gỏn cuối cựng (sel <= sel +2) hoặc đơn giản là đưa ra thụng bỏo lỗi và kết thỳc việc biờn dịch. Đõy cũng khụng bao giờ là vấn đề khi sử dụng VARIABLE.
s0 s1 a b c d y ns 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 s0 s1 a b c d y ns 50 100 150 200 250 300 350 400 450 500 550 600 Hỡnh 7.3b.2. Kết quả mụ phỏng cỏch 1 và 2 Vớ dụ 7.3c: DFF với q và qbar Hỡnh 7.3c.1. DFF Cỏch 1: Khụng đỳng
---- Solution 1: not OK --- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY dff IS PORT ( d, clk: IN STD_LOGIC; q: BUFFER STD_LOGIC; qbar: OUT STD_LOGIC); END dff;
ARCHITECTURE not_ok OF dff IS BEGIN
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN q <= d; qbar <= NOT q; END IF; END PROCESS; END not_ok; Cỏch 2: Đỳng ---- Solution 2: OK --- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY dff IS PORT ( d, clk: IN STD_LOGIC; q: BUFFER STD_LOGIC; qbar: OUT STD_LOGIC); END dff;
ARCHITECTURE ok OF dff IS BEGIN
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN q <= d; END IF; END PROCESS; qbar <= NOT q; END ok; Trong cỏch 1, cỏc phộp gỏn q<=d (dũng 16) và qbar<=NOT q (dũng 17) đều đồng bộ, vỡ vậy cỏc giỏ trị mới của chỳng sẽ chỉ được dựng lỳc kết thỳc PROCESS. Đõy là vấn đề đối với qbar, bởi vỡ giỏ trị mới của q khụng vừa mới tạo ra. Do đú, qbar sẽ nhận giỏ trị đảo giỏ trị cũ của q. Giỏ trị đỳng của qbar sẽ bị trễ một chu kỳ đồng hồ, gõy cho mạch làm việc khụng chớnh xỏc.
Trong cỏch 2, thay qbar<=NOT q (dũng 30) bờn ngoài PROCESS, do đú phộp tớnh như một biểu thức đồng thời đỳng.
d clk q qbar ns 50 100 150 200 250 300 350 400 450 500 550 600 d clk q qbar ns 50 100 150 200 250 300 350 400 450 500 550 600 Hỡnh 7.3c.2. Kết quả mụ phỏng cỏch 1 và 2 Vớ dụ 7.3d:
Bộ chia tần, chia tần số clock bởi 6.
Hỡnh 7.3d.1. Bộ chia tần
Thực hiện hai đầu ra, một là dựa trờn SIGNAL (count1), và một dựa trờn VARIABLE (count2). clk count1 count2 out1 out2 ns 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 0 1 2 3 4 5 6 0 1 2 3 7 4 Hỡnh 7.3d.2. Kết quả mụ phỏng LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY freq_divider IS PORT ( clk : IN STD_LOGIC;
out1, out2 : BUFFER STD_LOGIC); END freq_divider;
ARCHITECTURE example OF freq_divider IS SIGNAL count1 : INTEGER RANGE 0 TO 7; BEGIN
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk='1') THEN count1 <= count1 + 1; count2 := count2 + 1; IF (count1 = 7 ) THEN
out1 <= NOT out1; count1 <= 0; END IF;
IF (count2 = 7 ) THEN out2 <= NOT out2; count2 := 0; END IF; END IF; END PROCESS; END example; 7.4. Số thanh ghi.
Số flip-flop được suy ra từ mó bởi trỡnh biờn dịch. Mục đớch là khụng chỉ hiểu tiếp cận yờu cầu số thanh ghi tối thiểu, mà cũn đảm bảo đoạn mó thực hiện mạch mong muốn.
Một SIGNAL sinh một flip-flop bất cứ khi nào một phộp gỏn được tạo ra tại sự chuyển tiếp của tớn hiệu khỏc, khi một phộp gỏn đồng bộ xảy ra. Phộp gỏn đồng bộ, cú thể chỉ xảy ra bờn trong PROCESS, FUNCTION, hay PROCEDURE (thường là một khai bỏo kiểu “IF signal’EVENT …” hoặc “WAIT UNTIL …”).
Một VARIABLE sẽ khụng sinh cỏc flip-flop cần thiết nếu giỏ trị của nú khụng bao giờ rời PROCESS (hoặc FUNCTION, hoặc PROCEDURE). Tuy nhiờn, nếu một giỏ trị được gỏn cho một biến tại sự chuyển tiếp của tớn hiệu khỏc, và giỏ trị thậm chớ được đưa tới một tớn hiệu (rời PROCESS), thỡ cỏc flip- flop sẽ được suy ra. Một VARIABLE cũn sinh một thanh ghi khi nú được sử dụng trước một giỏ trị vừa được gỏn cho nú.
Vớ dụ:
Trong PROCESS, output1 và output2 đều sẽ được lưu trữ (suy ra cỏc flip- flop), bởi vỡ cả hai đều được gỏn tại sự chuyển tiếp của tớn hiệu khỏc (clk).
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN
output1 <= temp; -- output1 stored output2 <= a; -- output2 stored END IF;
END PROCESS;
Trong PROCESS tiếp theo, chỉ output1 được lưu trữ (output2 sẽ tạo cỏch sử dụng cỏc cổng logic).
BEGIN
IF (clk'EVENT AND clk='1') THEN
output1 <= temp; -- output1 stored END IF;
output2 <= a; -- output2 not stored END PROCESS;
Trong PROCESS, biến temp sẽ gõy ra tớn hiệu x để lưu trữ PROCESS (clk)
VARIABLE temp: BIT; BEGIN
IF (clk'EVENT AND clk='1') THEN temp <= a;
END IF;
x <= temp; -- temp causes x to be storedEND PROCESS; END PROCESS;
Vớ dụ 7.4a:
DFF với q và qbar
Cỏch 1 cú 2 phộp gỏn SIGNAL đồng bộ (dũng 16-17), vỡ vậy 2 flip-flop sẽ được sinh. Cỏch 2 cú một trong cỏc phộp gỏn là đồng bộ, việc tổng hợp sẽ luụn suy ra chỉ một flip-flop
Hỡnh 7.4a.1. Cỏc mạch suy ra từ mó của cỏch 1 và 2
d clk q qbar ns 50 100 150 200 250 300 350 400 450 500 550 600 d clk q qbar ns 50 100 150 200 250 300 350 400 450 500 550 600 Hỡnh 7.4a.2. Kết quả mụ phỏng cỏch 1 và 2 Cỏch 1: Sinh hai DFF
---- Solution 1: Two DFFs --- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY dff IS PORT ( d, clk: IN STD_LOGIC; q: BUFFER STD_LOGIC; qbar: OUT STD_LOGIC); END dff;
ARCHITECTURE two_dff OF dff IS BEGIN
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN
q <= d; -- generates a register
qbar <= NOT d; -- generates a register END IF; END PROCESS; END two_dff; Cỏch 2: Sinh một DFF ---- Solution 2: One DFF --- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY dff IS PORT ( d, clk: IN STD_LOGIC; q: BUFFER STD_LOGIC; qbar: OUT STD_LOGIC); END dff;
ARCHITECTURE one_dff OF dff IS BEGIN
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN
q <= d; -- generates a registerEND IF; END IF;
END PROCESS;
qbar <= NOT q; -- uses logic gate (no register) END one_dff;
Vớ dụ 7.4b:
Hỡnh 7.4b.1. Bộ đếm 0 – 7 Cỏch 1:
Một phộp gỏn VARIABLE đồng bộ được tao ra (dũng 14-15). Một VARIABLE cú thể sinh cỏc thanh ghi bởi vỡ phộp gỏn của nú (dũng 15) tại sự chuyển tiếp của tớn hiệu khỏc (clk, dũng 14) và giỏ trị của nú khụng rời PROCESS (dũng 17).
--- Solution 1: With a VARIABLE ---
ENTITY counter IS
PORT ( clk, rst: IN BIT;
count: OUT INTEGER RANGE 0 TO 7); END counter;
ARCHITECTURE counter OF counter IS BEGIN
PROCESS (clk, rst)
VARIABLE temp: INTEGER RANGE 0 TO 7; BEGIN
IF (rst='1') THEN temp:=0;
ELSIF (clk'EVENT AND clk='1') THEN temp := temp+1; END IF; count <= temp; END PROCESS; END counter; Cỏch 2: Một phộp gỏn SIGNAL đồng bộ xảy ra (dũng 13-14). Chỉ sử dụng cỏc SIGNAL. Chỳ ý, khi khụng cú tớn hiệu phụ được sử dụng, count cần được khai bỏo như kiểu BUFFER (dũng 14), bởi vỡ nú được gỏn một giỏ trị và cũng được đọc (sử dụng) nội tại (dũng 14). Một SIGNAL, giống như một VARIABLE, cú thể cũng được tăng khi sử dụng trong mó tuần tự.
--- Solution 2: With SIGNALS only ---
ENTITY counter IS
PORT ( clk, rst: IN BIT;
count: BUFFER INTEGER RANGE 0 TO 7); END counter;
BEGIN
PROCESS (clk, rst) BEGIN
IF (rst='1') THEN count <= 0;
ELSIF (clk'EVENT AND clk='1') THEN count <= count + 1;
END IF;END PROCESS; END PROCESS; END counter;
Từ 2 cỏch trờn, 3 flip-flop được suy ra (để giữ 3 bit tớn hiệu đầu ra count).
rst clk count ns 50 100 150 200 250 300 350 400 450 500 550 600 0 1 2 3 4 5 6 7 rst clk count ns 50 100 150 200 250 300 350 400 450 500 550 600 0 1 2 3 4 5 6 7 Hỡnh 7.4b.2. Kết quả mụ phỏng cỏch 1 và 2 Vớ dụ 7.4c: Thanh ghi dịch 4 cấp Hỡnh 7.4c.1. Thanh ghi dịch 4 cấp Cỏch 1:
3 VARIABLE được sử dụng (a, b, và c, dũng 10). Tuy nhiờn cỏc biến được sử dụng trước cỏc giỏ trị được gỏn cho chỳng (đảo ngược thứ tự, bắt đầu với dout, dũng 13, và kết thỳc với din, dũng 16). Kết quả là, cỏc flip-flop sẽ được suy ra, lưu trữ cỏc giỏ trị từ phộp chạy liền trước của PROCESS.
--- Solution 1: ---
ENTITY shift IS
PORT ( din, clk: IN BIT; dout: OUT BIT);
END shift;
ARCHITECTURE shift OF shift IS BEGIN
VARIABLE a, b, c: BIT; BEGIN
IF (clk'EVENT AND clk='1') THEN dout <= c; c := b; b := a; a := din; END IF; END PROCESS; END shift; Cỏch 2:
Cỏc biến được thay thế bởi cỏc SIGNAL (dũng 8), và cỏc phộp gỏn được tạo ra trong thứ tự trực tiếp (từ din-dout, dũng 13-16). Khi cỏc phộp gỏn tớn hiệu tại sự chuyển tiếp tớn hiệu khỏc sinh cỏc thanh ghi, mạch đỳng sẽ được suy ra. --- Solution 2: ---
ENTITY shift IS
PORT ( din, clk: IN BIT; dout: OUT BIT); END shift;
ARCHITECTURE shift OF shift IS SIGNAL a, b, c: BIT; BEGIN
PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN a <= din; b <= a; c <= b; dout <= c; END IF; END PROCESS; END shift; Cỏch 3:
Cỏc biến giống nhau của cỏch 1 đó bị chiếm, nhưng trong thứ tự trực tiếp (từ din-dout, dũng 13-16). Tuy nhiờn, một phộp gỏn cho một biến là tức thỡ, và khi cỏc biến đang được sử dụng trong thứ tự trực tiếp (sau khi cỏc giỏ trị vừa được gỏn cho chỳng), dũng 13-15 thành 1 dũng, tương đương với c:=din. Giỏ trị của c rời PROCESS trong dũng tiếp theo (dũng 16), khi một phộp gỏn tớn hiệu (dout <= c) xảy ra tại sự chuyển tiếp của clk. Do đú, một thanh ghi sẽ được suy ra từ cỏch 3, nờn khụng tạo kết quả mạch chớnh xỏc.
--- Solution 3: ---
ENTITY shift IS
PORT ( din, clk: IN BIT; dout: OUT BIT); END shift;
BEGIN
PROCESS (clk)
VARIABLE a, b, c: BIT; BEGIN
IF (clk'EVENT AND clk='1') THEN a := din; b := a; c := b; dout <= c; END IF; END PROCESS; END shift;
Đầu ra dout là bốn sườn clock dương sau đầu vào din ở cỏch 1, nhưng chỉ một sườn dương sau đầu vào ở cỏch 2.
din clk dout ns 50 100 150 200 250 300 350 400 450 500 550 600 din clk dout ns 50 100 150 200 250 300 350 400 450 500 550 600 din clk dout ns 50 100 150 200 250 300 350 400 450 500 550 600 Hỡnh 7.4c.2. Kết quả mụ phỏng cỏch 1, 2, và 3 Vớ dụ 7.4d:
Thanh ghi dịch 4 bit
Hỡnh 7.4d.1. Thanh ghi dịch 4 bit
Bit ra (q) phải là 4 sườn clock dương sau bit vào (d). Reset phải là khụng đồng bộ, xoỏ tất cả cỏc đầu ra flip-flop về ‘0’ khi kớch hoạt.
Sử dụng một SIGNAL để sinh cỏc flip-flop. Cỏc thanh ghi được tạo bởi vỡ một phộp gỏn cho một tớn hiệu được tạo ra tại sự chuyển tiếp của tớn hiệu khỏc (dũng 17-18).
---- Solution 1: With an internal SIGNAL ---
LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY shiftreg IS PORT ( d, clk, rst: IN STD_LOGIC; q: OUT STD_LOGIC); END shiftreg;
ARCHITECTURE behavior OF shiftreg IS
SIGNAL internal: STD_LOGIC_VECTOR (3 DOWNTO 0); BEGIN
PROCESS (clk, rst) BEGIN
IF (rst='1') THEN
internal <= (OTHERS => '0'); ELSIF (clk'EVENT AND clk='1') THEN
internal <= d & internal(3 DOWNTO 1); END IF;