Nghiên cứu Khoa học
NGHIÊN CỨU HỆ THỐNG NHÚNG TRÊN KIT FPGA ĐỂ THIẾT KẾ VÀ THỰC HIỆN IP CORE ALU
Một đơn vị số học và logic là phần lõi của đơn vị xử lý trung tâm CPU. ALU bao gồm mạch logic tổ hợp thực hiện tập phép toán số học và logic trên 2 bus ngõ vào. ALU có n ngõ vào nhị phân dùng để chọn thao tác nào cần thực hiện. Các đường tín hiệu chọn được giải mã bên trong ALU nhằm cung cấp đến 2n thao tác khác nhau.
Bảng giá trị các phép toán số học và logic:
S2 |
S1 |
S0 |
Phép toán |
Chức năng |
Khối thực hiện |
1 |
1 |
1 |
Y<=A+B |
A Cộng B |
Đơn vị số học |
1 |
1 |
0 |
Y<=A-B |
A trừ B |
Đơn vị số học |
1 |
0 |
1 |
Y<=A*B |
A Nhân B |
Đơn vị số học |
1 |
0 |
0 |
Y<=A/B |
A Chia B |
Đơn vị số học |
0 |
1 |
1 |
Y<=A&B |
A And B |
Đơn vị logic |
0 |
1 |
0 |
Y<=A | B |
A Or B |
Đơn vị logic |
0 |
0 |
1 |
Y<=A^B |
A Xor B |
Đơn vị logic |
0 |
0 |
0 |
Y<= ~B |
A Not B |
Đơn vị logic |
Bảng 4 Các phép toán số họcvà logic
Hình 1 : Cửa sổ XPS
Trong hộp thoại đầu tiên xuất hiện, cho phép chúng ta thao tác cơ bản:
Base Symtem Builder Wizard: hộp thoại này cho phép chúng ta tạo ra một Project mới.
Open A Recent Project: mở một Project đã có sẵn. Ở đây sẽ bắt đầu với bước tạo một Project mới: nhấn OK khi chọn ở Base Symtem..., hộp thoại tiếp theo sẽ hiện ra.
Hình 2 Hộp thoại Create New XPS Profect
Ở hộp thoại này, phần mêm sẽ yêu cầu đặt tên cho thư mục chứa Project và các thư mục liên quan, nhấn Browse và tạo một thư mục với một đường dẫn cụ thể, ở đây mình sẽ đặt tên cho thư mục giaima, lưu ý nhấn Open 2 lần, chương trinh sẽ tự rạo ra file giaima.xmp trong thư mục chúng ta vừa tạo ra
Chọn I would like to create a new design option và kích next để tiếp tục.
Click Next xuất hiện hộp thoại Board Selection
Chọn I would like to create a symtem for a custom board, lần lượt chon sau:
- Architecture: Spartan-3
- Device :xc3s200
- Package: ft256
- Speed Grade -4
Hình 3 Hộp thoại Select Board
Click Next xuất hiện hộp thoại Sytemconfiguaration .
Hình 4 : Hộp thoại symtem configuaration.
Click Next xuất hiện hộp thoại Processor configuaration
Chọn các thông số như sau:
- Reference Clock Frequency :50MHz
- Processor type: MicroBlaze
- System Clock Frequency – bus clock Frequency :50 MHz
- Local Memory :16KB
- Debug Interface: On-Chip H/W debug module
Hình 5 Hộp thoại Processor Configuaration
Click next xuất hiện hộp thoại Configuaration Peripheral
Hình 6 : Hộp thoại Configuaration Peripheral
Ở phần này ta chọn Add Device ->trong IO Interface Type chọn GPIO-> trong phần Device ta chọn Dip_switches và chọn OK như hình sau:
Hình 7: Add IO Devices for Generic Board
Tương tự ta chọn push_Buttons như trên. Tiếp tục trong IO Interface Type chon UART chon device RS232.
Click apply để add các thiết bị đã chọn.
Thay đổi các thông số như hình sau :
Hình 8 Bảng thông số Processor Peripherals
Click nex xuất hiện hộp thoại Cache configuration.
Hình 9 Hộp thoại Cache configuration
Click next xuất hiện Application Configuration
Hình 10: Hộp thoại Application Configuration
Click next xuất hiện hộp thoại Summary
Hình 11: Hộp thoại Summary
Chọn Finish để hoàn thành quá trình tạo Project. Nếu hộp thoại Next step xuất hiện thì chọn mục Start Using Platform Studio và click OK.
Cửa sổ System Assembly View 1 xuất hiện, thể hiện sự kết nối của hệ thống ngoại vi và hệ thống bus.
Hình 12: Cửa sổ System Assembly View
Chọn Project Generate and View Block Diagram để thể hiện sơ đồ khối phần cứng.
Hình 13 Block Diagram View of the Generated Project
Như vậy ta đã xây dựng xong phần cứng cở bản. Trong thực tế, nếu người dùng cần thêm ngoại vi cho thiết kế thì có nhiều cách thêm ngoại vi .
3.1 Sơ đồ khối hệ thống
Hình 14: Sơ đồ khối của hệ thống
3.2 Lưu đồ thuật toán
Hình 15 Lưu đồ thuật toán
4.3.3 Code User logic:
--Phần khai báo thư viện
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library proc_common_v3_00_a;
use proc_common_v3_00_a.proc_common_pkg.all;
--Khai báo thực thể
entity user_logic is
generic
(
C_SLV_DWIDTH : integer := 32;
C_NUM_REG : integer := 3
);
port
(
Bus2IP_Clk : in std_logic;
Bus2IP_Reset : in std_logic;
Bus2IP_Data : in std_logic_vector(0 to C_SLV_DWIDTH-1);
Bus2IP_BE : in std_logic_vector(0 to C_SLV_DWIDTH/8-1);
Bus2IP_RdCE : in std_logic_vector(0 to C_NUM_REG-1);
Bus2IP_WrCE : in std_logic_vector(0 to C_NUM_REG-1);
IP2Bus_Data : out std_logic_vector(0 to C_SLV_DWIDTH-1);
IP2Bus_RdAck : out std_logic;
IP2Bus_WrAck : out std_logic;
IP2Bus_Error : out std_logic
);
attribute SIGIS : string;
attribute SIGIS of Bus2IP_Clk : signal is "CLK";
attribute SIGIS of Bus2IP_Reset : signal is "RST";
end entity user_logic;
--Khai báo kiến trúc
architecture IMP of user_logic is
--USER signal declarations added here, as needed for user logic
signal sum : std_logic_vector(0 to C_SLV_DWIDTH -1 );
signal Sel : std_logic_vector(0 to 2);
--Khai báo các tín hiệu sử dụng
signal slv_reg0 : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_reg1 : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_reg2 : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_reg_write_sel : std_logic_vector(0 to 2);
signal slv_reg_read_sel : std_logic_vector(0 to 2);
signal slv_ip2bus_data : std_logic_vector(0 to C_SLV_DWIDTH-1);
signal slv_read_ack : std_logic;
signal slv_write_ack : std_logic;
begin
slv_reg_write_sel <= Bus2IP_WrCE(0 to 2);
slv_reg_read_sel <= Bus2IP_RdCE(0 to 2);
slv_write_ack <= Bus2IP_WrCE(0) or Bus2IP_WrCE(1) or Bus2IP_WrCE(2);
slv_read_ack <= Bus2IP_RdCE(0) or Bus2IP_RdCE(1) or Bus2IP_RdCE(2);
-- implement slave model software accessible register(s)
SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is
begin
if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
if Bus2IP_Reset = '0' then
slv_reg0 <= (others => '0');
slv_reg1 <= (others => '0');
slv_reg2 <= (others => '0');
else
case slv_reg_write_sel is
when "100" =>
for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
if ( Bus2IP_BE(byte_index) = '1' ) then
slv_reg0(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
end if;
end loop;
when "010" =>
for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
if ( Bus2IP_BE(byte_index) = '1' ) then
slv_reg1(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
end if;
end loop;
when "001" =>
for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
if ( Bus2IP_BE(byte_index) = '1' ) then
slv_reg2(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
end if;
end loop;
when others => null;
end case;
end if;
end if;
end process SLAVE_REG_WRITE_PROC;
-- implement slave model software accessible register(s) read mux
SLAVE_REG_READ_PROC : process( slv_reg_read_sel, slv_reg0, slv_reg1, slv_reg2, sum ) is
begin
--Khai báo đầu vào cho ALU
case slv_reg_read_sel is
when "100" => slv_ip2bus_data <= slv_reg0;
when "010" => slv_ip2bus_data <= slv_reg1;
when "001" => slv_ip2bus_data <= sum;
when others => slv_ip2bus_data <= (others => '0');
end case;
end process SLAVE_REG_READ_PROC;
alu_PROC : process(slv_reg0, slv_reg1) is
begin
if rising_edge(Bus2IP_Clk) then
if Bus2IP_Reset ='0' then Y <=x"0000";
else
--Khai báo chức năng của ALU
case Sel is
when "111" => sum <= slv_reg0 + slv_reg1;
when "110" => sum <= slv_reg0 - slv_reg1;
when "101" => sum <= slv_reg0 * slv_reg1;
when "100" => sum <= slv_reg0 / slv_reg1;
when "011" => sum <= slv_reg0 and slv_reg1;
when "010" => sum <= slv_reg0 or slv_reg1;
when "001" => sum <= slv_reg0 xor slv_reg1;
when others => Y <= not slv_reg1;
end process alu_PROC;
IP2Bus_Data <= slv_ip2bus_data when slv_read_ack = '1' else
(others => '0');
IP2Bus_WrAck <= slv_write_ack;
IP2Bus_RdAck <= slv_read_ack;
IP2Bus_Error <= '0';
end IMP;
// Khai báo thư viện
#include "xgpio.h"
#include "xparameters.h"
#include "xutil.h"
void usleep(unsigned int delay)
{
unsigned int j, i;
for(i=0; i<delay; i++)
for(j=0; j<26; j++);
}
// Chương trình chính
int main (void)
{
Xuint32 a,b, data, result, i;
XGpio push, dip;
XGpio_Initialize(&push, XPAR_PUSH_BUTTONS_DEVICE_ID);
XGpio_Initialize(&dip, XPAR_DIP_SWITCHES_DEVICE_ID);
// Set the peripheral to inputs
XGpio_SetDataDirection(&push, 1, 0x0000001F);
XGpio_SetDataDirection(&dip, 1, 0x0000001F);
do
{
do
{
data = XGpio_DiscreteRead(&push, 1); usleep(5000);
// Read the state of the 1 dip switches
a = XGpio_DiscreteRead(&dip, 1); usleep (50);
} while (data==0);
xil_printf("Data read from Push_Buttons_3Bit: 0x%x\r\n", data);
xil_printf("Data read from DIP_SWITCHES_8Bit: 0x%x\r\n", a);
// loop for delay for time to release switch and debounce
for(i=0; i <= 0x1FFFFFFF; i++) { ; }
// read another new 8-bit values from dip switches and signal to accept the new number for addition with the 3 push buttons
do{
data = XGpio_DiscreteRead(&push, 1); usleep(5000);
b = XGpio_DiscreteRead(&dip, 1); usleep (5000);
}while(data == 0);
xil_printf("Data read from Push_Buttons_3Bit: 0x%x\r\n", data);
xil_printf("Data read from DIP_Switches_8Bit: 0x%x\r\n", b);
// Tính toán ở khối ALU
if (data==0x7) result = a + b;
else if (data==0x6) result = a - b;
else if (data==0x5) result = a * b;
else if (data==0x4) result = a / b;
else if (data==0x3) result = a & b;
else if (data==0x2) result = a | b;
else if (data==0x1) result = a ^ b;
else result = ~ b;
// Print Result of Calculator
print("Custom Logic with User Input\r\n");
xil_printf("a= %d\r\n",a);
xil_printf("b= %d\r\n",b);
xil_printf("Ket qua = %d\r\n",result);
for(i=0; i <= 0x1FFFFFFF; i++) { ; }
}while(1); // continues for ever to get user input
print("-- Exiting main() --\r\n\n\n");return 0;
}
1/ Thiết kế mạch số với VHDL và Verilog ( tập 1 và 2)- Tống Văn On, NXB lao động xã hội, Hà Nội, 2007
2/ Ngôn ngữ VHDL để thiết kế vi mạch - Nguyễn Quốc Tuấn, NXB Đại học Quốc gia TP Hồ Chí Minh 2010.
3/ Circuit Design with VHDL by Volnei A. Pedroni, MIT Press Cambridge, 2005
4/ The VHDL Cookbook by Peter J. Ashenden, 2007
5/ VHDL. Programming by Example, McGraw Hill, 4th Edition
6/ Website: www.xilinx.com
7/ Vhdl-Modeling-Electrical-Engineering của Analysis và Circuit design with vhd.
8/ McGraw Hill - VHDL. Programming by Example, 4th Edition.
9/ Xilinx logic handbook by Karen Parnell and Nick Mehta (2003)
10/ Circuit Design with VHDL by Volnei A. Pedroni, MIT Press Cambridge, 2005