Khối phục vụ ch−ơng trình

Một phần của tài liệu Thiết kế bộ vi xử lý 8 bit sử dụng công nghệ FPGA (Trang 61 - 67)

n đ−ợc thiết lập hoặc xoá dựa trê kết quả của lda,ad, adc và sbc Các lệh adc và

4.4.2Khối phục vụ ch−ơng trình

Khối utility này khai báo kiểu con byte độ dài 8 bit kiểu STD_LOGIC_VECTOR, kiểu con ten độ dài 10 bit kiểu STD_LOGIC_VECTOR. Ngoài ra khai báo các hằng số có giá trị là các vector bit của các lệnh. Tên của các lệnh đ−ợc gán cho các mã tác vụ của lệnh đó. Khối utilities trình bày hai hàm add_cv và sub_cv. Hai hàm này thực hiện cộng và trừ hai toán hạng kiểu std_logic_vector có độ dài 8 bit. Kết quả trả về là kiểu bit vector có chiều dài 8 + 2. Trong đó, bit có vị trí 8+1 chỉ thị cờ nhớ, bit có vị trí 8+2 chỉ thị cờ tràn. Hai giá trị ADDR_WIDTH và DATA_WIDTH là chiều dài bit của hai tuyến địa chỉ và dữ liệu.

PACKAGE UTILITY IS

CONSTANT ADDR_WIDTH: INTEGER := 2; CONSTANT DATA_WIDTH: INTEGER :=8; SUBTYPE byte IS std_logic_vector (7 DOWNTO 0);

SUBTYPE ten IS std_logic_vector (9 DOWNTO 0); SUBTYPE nibble IS std_logic_vector (3 DOWNTO 0); FUNCTION add_cv (a, b: byte; cin: std_logic) RETURN ten; FUNCTION sub_cv (a, b: byte; cin: std_logic) RETURN ten; FUNCTION set_if_zero (a: STD_LOGIC_VECTOR) RETURN STD_LOGIC;

CONSTANT zero_8: byte := "00000000";

CONSTANT int_66: STD_LOGIC_VECTOR (11 DOWNTO 0):= "000001100110";

CONSTANT zero_12: STD_LOGIC_VECTOR (11 DOWNTO 0):= "000000000000";

CONSTANT cla: std_logic_vector (3 DOWNTO 0):="0001"; CONSTANT cma: std_logic_vector (3 DOWNTO 0):="0010"; CONSTANT cmc: std_logic_vector (3 DOWNTO 0):="0100"; CONSTANT asl: std_logic_vector (3 DOWNTO 0):="1000";

57 Nguyễn Chí Kiên Chí Kiên

CONSTANT asr: std_logic_vector (3 DOWNTO 0):="1001"; CONSTANT jsr: std_logic_vector (2 DOWNTO 0):="110"; CONSTANT bra: std_logic_vector (3 DOWNTO 0):="1111"; CONSTANT indirect: std_logic:='1';

CONSTANT jmp: std_logic_vector (2 DOWNTO 0):="100"; CONSTANT sta: std_logic_vector (2 DOWNTO 0):="101"; CONSTANT lda: std_logic_vector (2 DOWNTO 0):="000"; CONSTANT ann: std_logic_vector (2 DOWNTO 0):="001"; CONSTANT adc: std_logic_vector (2 DOWNTO 0):="010"; CONSTANT sbc: std_logic_vector (2 DOWNTO 0):="011"; CONSTANT jsr_or_bra:std_logic_vector (1 DOWNTO 0):="11"; CONSTANT a_and_b: STD_LOGIC_VECTOR (5 DOWNTO 0):="000001";

CONSTANT b_compt: STD_LOGIC_VECTOR (5 DOWNTO 0):="000010";

CONSTANT a_input: STD_LOGIC_VECTOR (5 DOWNTO 0):="000100";

CONSTANT a_add_b: STD_LOGIC_VECTOR (5 DOWNTO 0):="001000";

CONSTANT b_input: STD_LOGIC_VECTOR (5 DOWNTO 0):="010000";

CONSTANT a_sub_b: STD_LOGIC_VECTOR (5 DOWNTO 0):="100000";

END UTILITY;

Trong thân khối utility trình bày hai giải thuật thực hiện hai phép toán cộng và trừ. Trong hàm cộng, kết quả phép cộng bit và cờ nhớ của nó đ−ợc tính nh− sau:

Sum := a XOR b XOR carry

Carry := ((a xor b) and carry) or ( a and b)

Vòng for thực hiện 8 phép cộng liên tiếp để tạo ra kết quả và cờ nhớ. Để xác định bit tràn, kiểm tra hai ngõ vào cùng dấu và kết quả khác dấu thì phép tính đã bị

58 Nguyễn Chí Kiên Chí Kiên

tràn. Nếu dấu_a bằng dấu_b và kết quả khác dấu_a thì tràn ng−ợc lại thì không tràn. Đối với phép trừ cũng t−ơng tự nh− phép cộng chỉ khác là tr−ớc khi thực hiện thì lấy số bù của b và cờ tràn.

PACKAGE BODY utility IS

FUNCTION add_cv (a, b: byte; cin: std_logic) RETURN ten IS VARIABLE r, c: ten := "0000000000";

VARIABLE a_sign, b_sign: std_logic := '0'; BEGIN

a_sign := a (a'LEFT); b_sign := b (b'LEFT);

r(0) := a(0) XOR b(0) XOR cin;

c(0):=((a(0) XOR b(0)) AND cin) OR (a(0) AND b(0)); FOR i IN 1 TO (a'LEFT) LOOP

r(i) := a(i) XOR b(i) XOR c(i-1);

c(i) := ((a(i) XOR b(i)) AND c(i-1)) OR (a(i) AND b(i)); (adsbygoogle = window.adsbygoogle || []).push({});

END LOOP;

r(a'LEFT+1) := c(a'LEFT);

IF a_sign = b_sign AND r(a'LEFT) /= a_sign THEN r (a'LEFT+2) := '1';

ELSE r (a'LEFT+2) := '0'; END IF;

RETURN r; END add_cv;

FUNCTION sub_cv (a, b: byte; cin: std_logic) RETURN ten IS VARIABLE not_b: byte := zero_8;

VARIABLE not_c: std_logic;

VARIABLE r, c: ten := "0000000000"; VARIABLE a_sign, b_sign: std_logic := '0'; BEGIN

59 Nguyễn Chí Kiên Chí Kiên

not_b := NOT b; not_c := NOT cin; a_sign := a(a'LEFT); b_sign := not_b(b'LEFT);

r(0) := a(0) XOR not_b(0) XOR not_c; c(0) := ((a(0) XOR not_b(0)) AND not_c) OR (a(0) AND not_b(0));

FOR i IN 1 TO (a'LEFT) LOOP

r(i) := a(i) XOR not_b(i) XOR c(i-1);

c(i) := ((a(i) XOR not_b(i)) AND c(i-1)) OR (a(i) AND not_b(i));

END LOOP;

r(a'LEFT+1) := NOT c(a'LEFT);

IF a_sign = b_sign AND r(a'LEFT) = a_sign THEN r(a'LEFT+2) := '1'; ELSE r(a'LEFT+2) := '0'; END IF; RETURN r; END sub_cv; END utility; 4.4.3. Mô tả hành vi cpu

Mô tả hành vi của CPU bằng lệnh cpu: PROCESS (clk_cpu)

Khai báo các biến cần thiết cho ch−ơng trình BEGIN

Wait UNTIL clk_cpu = ‘0’;

IF reset =’0’ THEN Đặt các trạng thái ban đầu ELSE

CASE state IS

WHEN S0 | S10 => Đặt biến về ban đầu

60 Nguyễn Chí Kiên Chí Kiên

IF interrup = ‘1’ THEN Xử lý ngắt quãng

ELSE

Phát tín hiệu độc bộ nhớ END IF;

WHEN S1 =>

IF interrup =’1’ THEN Trở về trạng thái S10 ELSE

Đọc dữ liệu trên bus đ−a vào byte1, tăng PC+ 1 IF byte1 (7 downto 4) = lệnh một byte THEN (adsbygoogle = window.adsbygoogle || []).push({});

Thực hiện lệnh 1 byte ELSE Đặt trạng thái S2; END IF; END IF; WHEN S2 => Phát tín hiệu đọc bộ nhớ đặt trạng thái S3 WHEN S3 =>

Đọc dữ liệu vào byte 2, tăng PC + 1

IF byte1 (7 downto 4) = rẽ nhánh THEN Thực hiện lệnh rẽ nhánh, địa chỉ trong byte 2

ELSIF byte1 (4) /= lệnh gián tiếp AND byte1(7 downto 5)=jmp

THEN

Thực hiện lệnh nhảy trực tiếp ELSE Đặt trạng thái s4 END IF;

WHEN S4 => Đặt trạng thái S5

IF byte1 (7 down to 5) = jsr THEN Phát xung ghi bộ nhớ

61 Nguyễn Chí Kiên Chí Kiên

IF byte1(4) = lệnh gián tiếp THEN Phát byte2 ra tuyến địa chỉ Phát xung đọc bộ nhớ

ELSIFbyte1(7 downto 5)=sta trực tiếp THEN Phát byte1(3-0)&byte2 ra tuyến địa chỉ Nạp ac vào tuyến dữ liệu

Phát xung ghi bộ nhớ ELSE

Phát byte1(3-0)&byte2 ra tuyến địa chỉ Phát xung đọc bộ nhớ

END IF; WHEN S5 =>

IF lệnh jsr THEN Thực hiện lệnh jsr

ELSIF lệnh sta trực tiếp THEN Kết thúc xung ghi

ELSIF lệnh gián tiếp THEN Đọc byte thứ 3 vào byte 2 Đặt trạng thái s6

IF byte1 (7 downto 5) jmp THEN Thực hiện lệnh jmp gián tiếp END IF;

ELSE

Thực hiện lệnh trực tiếp lda, and, adc, sbc END IF;

WHEN S6 =>

Đặt trạngthái S7

IF byte1 (7 downto 5) = sta THEN

Phát byte1(3-0)&byte2 ra tuyến địa chỉ Nạp ac vào tuyến data

62 Nguyễn Chí Kiên Chí Kiên

ELSE

Phát byte1(3-0)&byte2 ra tuyến địa chỉ Phát xung đọc bộ nhớ

END IF; WHEN s7 => IF lệnh sta gián tiếp THEN Kết thúc xung ghi

ELSE Thực hiện lệnh gián tiếp lda, and, adc, sbc

END IF; Trở về trạng thái S10 END IF; (adsbygoogle = window.adsbygoogle || []).push({});

END PROCESS;

Một phần của tài liệu Thiết kế bộ vi xử lý 8 bit sử dụng công nghệ FPGA (Trang 61 - 67)