Giáo trình Thực hành Thiết kế logic số

pdf 70 trang ngocly 2440
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Thực hành Thiết kế logic số", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfgiao_trinh_thuc_hanh_thiet_ke_logic_so.pdf

Nội dung text: Giáo trình Thực hành Thiết kế logic số

  1. Phục lục I: Thực hành mô phỏng VHDL trên ModelSim 1. Giới thiệu về chương trình mô phỏng Modelsim. Do các ngôn ngữ mô tả phần cứng như VHDL được chuẩn hóa bởi IEEE và được công bố rộng rãi nên có rất nhiều các phần mềm mô phỏng mạch số được nhiều công ty khác nhau phát triển. Điểm chung của các chương trình này là đều phải có một trình biên dịch và có khả năng mô phỏng mạch theo thời gian thực, kết xuất kết quả một số dạng nhất định như File text, file định kiểu, hay phổ biến và trực quan nhất là dưới dạng giản đồ sóng. Dưới đây sẽ giới thiệu chương trình mô phỏng là ModelSim, đây là một chương trình mô phỏng khá mạnh và chính xác được phát triển bởi Mentor Graphics. ModelSim là một chương trình phần mềm thương mại, tuy vậy bên cạnh các phiên bản phải trả tiền license, có phiên bản miễn phí dành cho sinh viên
  2. và người nghiên cứu không sử dụng với mục đích thương mại. Phiên bản này có tên là ModelSim Student Edition có thể được tải trực tiếp từ trang chủ của Mentor Graphics theo địa chỉ Sau khi cài chương trình sẽ đòi hỏi cài đặt cấp phép sử dụng (license). Để có được license cần phải điều đủ vào bản khai báo các thông tin cá nhân như hòm thư, địa chỉ vv Mentor Graphic sẽ gửi vào hòm thư của bạn một file license có tên là student_license.dat, file này cho phép sử dụng phần mềm trong vòng 180 ngày, để kích hoạt license chỉ việc copy vào thư mục gốc của modelSim (thường là C:\Modeltech_pe_edu_6.2f trong đó “6.2f” là số hiệu phiên bản của chương trình) Chú ý: Hướng dẫn mô phỏng một thiết kế và sử dụng chương trình có trong thư mục “C:\Modeltech_pe_edu_6.2f\docs\pdfdocs”, đối với các phiên bản khác nhau thì có thể đường dẫn sẽ khác nhau. Sau đây chúng ta sẽ lần lượt học cách sử dụng chương trình thông qua một ví dụ cụ thể. 2. Viết mã nguồn VHDL Trong Modelsim cũng tích hợp một trình soạn thảo file nguồn tuy vậy cũng như các ngôn ngữ lập trình khác mã nguồn VHDL của thiết kế có thể được soạn thảo bằng bất kz một chương trình soạn thảo nào. Một trong những chương trình soạn thảo khá tốt và tiện dụng là Notepad++ ( plus-plus.org/download), chương trình này hỗ trợ hiện thị nhiều ngôn ngữ lập trình khác nhau trong đó có VHDL và Verilog. File nguồn của mã VHDL có đuôi là .vhd. Khi soạn thảo file có đuôi dạng này băng Notepad thì toàn bộ các từ khóa, cấu trúc ngôn ngữ được làm đậm hoặc đổi màu cho dễ quan sát và sửa lỗi.
  3. Chương trình Notepad++ Để đơn giản và dễ hiểu phần này ta sẽ minh họa bằng ví dụ quen thuộc về bộ cộng 4 bit. Bộ cộng được thiết kế đơn giản nhất bằng cách ghép nối tiếp 4 khối full_adder 1 bit. b3 a3 b2 a2 b1 a1 b0 a0 C(2) C(1) C(0) CI FULL_ADDER FULL_ADDER FULL_ADDER FULL_ADDER CO S3 S2 S1 S0 Cấu trúc của 4 bit - adder Module full_adder có ba mô tả kiến trúc, trong đó mô tả cấu trúc sử dụng các module con là AND2, OR2, XOR2. Bước 1: Tạo trong thư mục D:\Student một thư mục có tên adder4. Thư mục chúng ta làm việc sẽ là D:\Student\adder4 Bước 2: Trong Notepad++ tạo mới một file bằng cach chọn menu File/new, soạn thảo file với nội dung sau, soạn thảo xong đó chọn File/Save, và lưu file dưới tên compn.vhd trong thư mục làm việc D:\Student\adder, lưu { để lưu dưới dạng vhd ở ô chọn File types phải chọn là All files(*)
  4. Nội dung file compn.vhd full_adder component library IEEE; use IEEE.STD_LOGIC_1164.ALL; 2 input AND gate entity AND2 is port( in1, in2 : in std_logic; out1 : out std_logic ); end AND2; architecture model_conc of AND2 is begin out1 <= in1 and in2; end model_conc; library IEEE; use IEEE.STD_LOGIC_1164.ALL; 2 input OR gate entity OR2 is port( in1, in2 : in std_logic; out1 : out std_logic ); end OR2;
  5. architecture model_conc2 of OR2 is begin out1 <= in1 or in2; end model_conc2; library IEEE; use IEEE.STD_LOGIC_1164.ALL; 2 input XOR gate entity XOR2 is port( in1, in2 : in std_logic; out1 : out std_logic ); end XOR2; architecture model_conc2 of XOR2 is begin out1 <= in1 xor in2; end model_conc2; Bước 3: Tạo file full_adder.vhd trong thư mục làm việc có nội dung như sau: full_adder library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.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 behavioral of full_adder is BEGIN add: process (A, B, Cin) begin if (a ='0' and b='0' and Cin = '0') then S <= '0'; Cout <= '0'; elsif (a = '1' and b = '0' and Cin = '0') or (a = '0' and b = '1' and Cin = '0') or (a = '0' and b = '0' and Cin = '1') then S <= '1';
  6. Cout <= '0'; elsif (a = '1' and b = '1' and Cin = '0') or (a = '1' and b = '0' and Cin = '1') or (a = '0' and b = '1' and Cin = '1') then S <= '0'; Cout <= '1'; elsif (a = '1' and b = '1' and Cin = '1') then S <= '1'; Cout <= '1'; end if; end process add; end behavioral; 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; architecture structure of full_adder is signal t1, t2, t3 : std_logic; components declaration component OR2 port ( in1, in2 : in std_logic; out1 : out std_logic ); end component; component AND2 port (in1, in2 : in std_logic; out1: out std_logic ); end component; component XOR2 port (in1, in2: in std_logic; out1 : out std_logic ); end component; begin u1 : XOR2 port map (a, b, t1); u2 : XOR2 port map (t1, Cin, S); u3 : AND2 port map (t1, Cin, t2); u4 : AND2 port map (a, b, t3); u5 : OR2 port map (t3, t2, Cout); end structure; Bước 4: Tạo mã nguồn của bộ cộng 4-bit, lưu thành file adder4.vhd với nội dung như sau:
  7. 4-bit adder library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity adder4 is port( A : in std_logic_vector(3 downto 0); B : in std_logic_vector(3 downto 0); CI : in std_logic; SUM : out std_logic_vector(3 downto 0); CO : out std_logic); end adder4; architecture structure of adder4 is signal C: std_logic_vector(2 downto 0); declaration of component full_adder component full_adder port ( A : in std_logic; B : in std_logic; Cin : in std_logic; S : out std_logic; Cout : out std_logic ); end component; for u0: full_adder use entity work.full_adder(structure); for u1: full_adder use entity work.full_adder(behavioral); for u2: full_adder use entity work.full_adder(dataflow); for u3: full_adder use entity work.full_adder(dataflow); begin design of 4-bit adder u0: component full_adder port map (A => A(0), B => B(0), Cin => CI, S =>Sum(0), Cout => C(0)); u1: component full_adder port map (A => A(1), B => B(1), Cin => C(0), S =>Sum(1), Cout => C(1)); u2: component full_adder port map (A => A(2), B => B(2), Cin => C(1), S =>Sum(2), Cout => C(2)); u3: component full_adder port map (A => A(3), B => B(3), Cin => C(2), S =>Sum(3), Cout => CO); end structure;
  8. Theo như trình bày ở phần lý thuyết của khai báo cấu hình, nếu ta dung phương pháp khai báo trực tiếp cấu hình như trên thì các component full_adder của adder4 được lựa chọn các cấu hình khác nhau như ở trên. 3. Biên dịch thiết kế. Để tạo biên dịch thiết kế ta làm lần lượt các bươc sau: Bước 5: Khởi động Modelsim, tại menu File chọn Change Directory, tại menu Change directory chọn Chọn đường dẫn tới thư mục làm việc D:\Student\adder4\ chứa các nguồn vừa tạo adder4.vhd, full_adder.vhd, compn.vhd Bước 6: Tạo thư viện work bằng cách gõ lệnh sau vào cửa sổ Transcript của Modelsim: vlib work
  9. Bước 7: Biên dịch các mã nguồn bằng cách gõ các lệnh sau vào cửa số Transcript vcom compn.vhd vcom full_adder.vhd vcom adder4.vhd
  10. Khi trình biên dịch phát hiện ra lỗi về mặt cú pháp thì nó sẽ thông báo chính xác dòng tương ứng gây ra lỗi. Nếu như mã nguồn của thiết kế không có lỗi thì biên dịch xong sẽ cho ra kết quả như hình trên. 4. Kiểm tra và mô phỏng thiết kế. 4.1 Kiểm tra nhanh Quick test: Kiểm tra nhanh thiết kế bằng cách đưa vào đầu vào của DUT các giá trị cố định và kiểm tra trực tiếp kết quả đầu ra. Kiểm tra nhanh cho phép phát hiện và sửa những lỗi về mặt chức năng đơn giản trước khi bước vào bước kiểm tra với số lượng lớn tổ hợp giá trị đầu vào. Bước 8: Để kiểm tra nhanh bộ cộng thiết kế ở trên tạo thêm một file adder4_test.vhd trong thư mục làm việc với nội dung như sau như sau: adder4_test library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity adder4_test is end adder4_test; architecture test of adder4_test is component adder4 is port( A : in std_logic_vector(3 downto 0); B : in std_logic_vector(3 downto 0); CI : in std_logic; SUM : out std_logic_vector(3 downto 0); CO : out std_logic ); end component; khai bao cac tin hieu vao ra cho DUT signal A : std_logic_vector(3 downto 0) := "0101"; signal B : std_logic_vector(3 downto 0) := "1010"; signal CI : std_logic := '1'; output signal SUM : std_logic_vector(3 downto 0); signal CO : std_logic; begin DUT: component adder4 port map ( A => A, B=> B, CI => CI, SUM => SUM, CO =>CO );
  11. end test; test_adder4 là một thiết kế mà không chứa bất cứ cổng vào ra nào ở phần khai báo. Kiến trúc của nó gồm hai phần, phần khai báo tín hiệu sẽ khai báo các tín hiệu vào ra của adder4 trong đó đối với các tín hiệu đầu vào a_t = “0011”, b_t = “0110”, ci_t = ‘0’; đối với các tín hiệu đầu ra thì để trống. Phần hai là khai báo sử dụng adder4 như một phần tử có tên là dut (component) và gán các cổng vào ra tương ứng như trên. Bước 9: Tiến hành biên dịch file adder4_test.vhd này bằng lệnh sau trong cửa sổ transcript tương tự làm trong bước 7). vcom adder4_test.vhd Bước 10: Khởi tạomô phỏng thiết kế bằng lệnh: vsim adder4_test Bước 11: Bổ xung các tín hiệu vào cửa sổ wave form để quan sát, để thực hiện gõ các lệnh sau vào cửa sổ Transcript add wave sim:/adder4_test/dut/a add wave sim:/adder4_test/dut/b
  12. add wave sim:/adder4_test/dut/CI add wave sim:/adder4_test/dut/CO add wave sim:/adder4_test/dut/SUM Mỗi lệnh trên sẽ hiển thị một tín hiệu tương ứng vào giản đồ sóng, bằng cách đó ta có thể lựa chọn các tín hiệu nhất định để theo dõi. Sau khi thực hiện các bước trên thì có thể tiến hành chạy mô phỏng. Mô phỏng có thể chạy bằng nút công cụ Run trên thanh công cụ của cửa sổ giản đồ sóng: Bước 12: Chạy mô phỏng và quan sát kết quả trên waveform bằng cách gõ lệnh run 100 ns vào cửa sổ Transcript sau đó mở rộng cửa sổ Waveform bên phải để quan sát. run 1000 ns Khi gặp lệnh này chương trình sẽ chạy mô phỏng trong 100us. Kết quả ra như sau:
  13. Quan sát trên hình có và so sánh với mã nguồn của adder4_testbench có thể thấy với a = “0101” = 5, b=”1010” = 15, CI = ‘1’ thì cho ra kết quả sum = “0000” = 0 và CO = ‘1’. 4.2 Kiểm tra toàn bộ full test: Là dạng kiểm tra với tất cả các tổ hợp xác định có thể có của đầu vào, trong ví dụ trên ta có 3 tính hiệu đầu vào là a(3:0), b(3:0), CI, vì vậy tổ hợp tất cả các tính hiệu đầu vào là 24 * 2 *4 *21 = 29 = 512 tổ hợp. Rõ ràng đối với khả năng của máy tính hiện đại đây là một con số rất nhỏ. Như vậy module của adder4 có thể được kiểm tra với độ tin cậy lên tới 100%. Bước 13: Tạo module chuẩn là adder4_etalon với nội dung sau và lưu vào trong thư mục làm việc với tên adder4_etalon.vhd adder 4-bit etalon library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity adder4_etalon is port(
  14. A : in std_logic_vector(3 downto 0); B : in std_logic_vector(3 downto 0); CI : in std_logic; SUM : out std_logic_vector(3 downto 0); CO : out std_logic); end adder4_etalon; architecture behavioral of adder4_etalon is signal s_sig: std_logic_vector(4 downto 0); signal a_sig: std_logic_vector(4 downto 0); signal b_sig: std_logic_vector(4 downto 0); begin a_sig <= '0' & A; b_sig <= '0' & B; plus: process (a_sig, b_sig, CI) begin s_sig <= a_sig + b_sig + CI; end process plus; SUM <= s_sig (3 downto 0); CO <= s_sig (4); end behavioral; Bước 14: Tạo module kiểm tra toàn bộ adder4_testbench. Mã nguồn này được lưu trong file adder4_testbench.vhd với nội dung như sau adder 4 testbench_full library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; library STD; use STD.TEXTIO.ALL; entity adder4_testbench is end adder4_testbench; architecture testbench of adder4_testbench is signal a_t : std_logic_vector(3 downto 0) := "0000"; signal b_t : std_logic_vector(3 downto 0) := "0000"; signal sum_t : std_logic_vector(3 downto 0); signal sum_e : std_logic_vector(3 downto 0); signal ci_t : std_logic := '0'; signal co_t : std_logic; signal co_e : std_logic; signal clk : std_logic := '0'; component adder4 port (A : in std_logic_vector (3 downto 0); B : in std_logic_vector (3 downto 0);
  15. CI : in std_logic; SUM : out std_logic_vector (3 downto 0); CO : out std_logic ); end component; component adder4_etalon port (A : in std_logic_vector (3 downto 0); B : in std_logic_vector (3 downto 0); CI : in std_logic; SUM : out std_logic_vector (3 downto 0); CO : out 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; check: process (clk) variable info: line; variable test_cnt: integer := 0; begin if clk = '1' and clk'event then write(info, string'("Test # ")); write(info, integer'(test_cnt + 1)); write(info, string'(" a = ")); write(info, integer'(conv_integer(a_t))); write(info, string'(" b = ")); write(info, integer'(conv_integer(b_t))); write(info, string'(" CI = ")); write(info, integer'(conv_integer(ci_t))); write(info, string'(" sum = ")); write(info, integer'(conv_integer(sum_t))); write(info, string'(" CO = ")); write(info, integer'(conv_integer(co_t))); write(info, string'(" sum_e = ")); write(info, integer'(conv_integer(sum_e))); write(info, string'(" CO_e = ")); write(info, integer'(conv_integer(co_e))); if sum_e /= sum_t or co_e /= co_t then write(info, string'("FAILURE")); else write(info, string'(" OK")); end if; writeline(output, info); input data generator.
  16. test_cnt := test_cnt + 1; ci_t a_t, B => b_t, CI => ci_t, SUM =>sum_t, CO => co_t); etalon: adder4_etalon port map (A => a_t, B => b_t, CI => ci_t, SUM =>sum_e, CO => co_e); END testbench; Bước 15 Biên dịch và mô phỏng moduel adder4_testbench bằng các lệnh: vcom adder4_etalon.vhd vcom adder4_testbench.vhd vsim adder4_testbench add wave sim:/adder4_testbench/a_t add wave sim:/adder4_testbench/b_t add wave sim:/adder4_testbench/CI_t add wave sim:/adder4_testbench/CO_t add wave sim:/adder4_testbench/SUM_t run 1000 ns Kết quả thu được như sau:
  17. Kết quả ngoài xuất ra trên của sổ waveform còn được xuất ra trên của sổ transcript bằng lệnh writeline, mỗi dòng tương ứng với một tổ hợp kiểm tra, khi có sai sót thì ở cuối dòng sẽ có báo “FAILURE”, còn nếu như kết quả đúng thì báo “OK”. Bước 16: Gõ tiếp lệnh lệnh run cho tới khi tất cả 512 trường hợp kiểm tra hoàn thành, quan sát kết quả trên cửa sổ transcript. run 1000 ns 5. Tạo file TCL script. Trên thực tế khi viết mã nguồn cũng như mã kiểm tra thường xảy ra rất nhiều các sai sót và việc biên dịch lại và kiểm tra lại nhiều lần là không thể tránh khỏi. Để tiết kiệm thời gian thì các động tác biên dịch, mô phỏng, bổ xung vào giản đồ sóng và nhiều các lệnh khác được hỗ trợ trên cửa sổ transcript có thể được lưu vào một file text bất kz và thực thi chỉ bằng một lệnh duy nhất. Bước 17: Tạo một file run.do lưu vào trong thư mục làm việc với nội dung như sau: vsim -quit vlib work vcom compn.vhd vcom full_adder.vhd vcom adder4.vhd vcom adder4_etalon.vhd
  18. vcom adder4_testbench.vhd vsim adder4_testbench add wave sim:/adder4_testbench/a_t add wave sim:/adder4_testbench/b_t add wave sim:/adder4_testbench/CI_t add wave sim:/adder4_testbench/CO_t add wave sim:/adder4_testbench/SUM_t run 1000 ns Dòng thứ nhất để kết thúc bất kz mô phỏng nào đang thực thi nếu nó tồn tại, dòng thứ hai tạo thư viện work nếu nó chưa tồn tại, tiếp đến là các lệnh vcom để biên dịch các file mã nguồn từ thấp đến cao. Lệnh vsim để tiến hành mô phỏng, sau đó là các lệnh bổ xung tín hiệu cần theo dõi vào giản đồ sóng. Lệnh cuối cùng là lệnh run dùng để chạy mô phỏng. Bước 18: trong cửa sổ transcript của modelsim để biên dịch và chạy lại mô phỏng ta chỉ như sau. do run.do Cách tiếp cận này rõ ràng thuận tiện và nhanh chóng hơn nhiều so với việc sử dụng giao diện đồ họa, đặc biệt khi làm việc với các thiết kế có số lượng cổng vào ra lớn và khó kiểm tra.
  19. Phụ lục 2: Hướng dẫn thực hành FPGA bằng Xilin ISE và Kit SPARTAN 3E 1. Cấu hình chương trình Modelsim để hỗ trợ các thư viện UNISIM, SIMPRIM. Chương trình Modelsim theo ngầm định không hỗ trợ các thư viện thiết kế FPGA của Xilinx là UNISIM và SIMPRIM. Phiên bản ISE 11.1 sử dụng Modelsim là chương trình mô phỏng ngầm định nhưng các thư viện trên chỉ hỗ trợ với các phiên bản Modelsim từ 6.4e trở đi. Hướng dẫn sau sẽ thực làm với bản Modelsim 6.5 Các bước để tích hợp thư viện như sau: - Tìm file modelsim.ini trong thư mục cài đặt C:\Modeltech 6.5, bỏ thuộc tính Read Only của file này trong hộp thoại Properties của file. - Khởi động Modelsim và tại cửa sổ Tcl script gõ lệnh biên dịch thư viện FPGA compxlib
  20. compxlib - Lệnh này sẽ khởi động chương trình Xilinx Simulation Library Compilation Wizard, sau đó thực hiện lần lượt theo các bước sau - chọn trình mô phỏng, trong trường hợp này là Modelsim SE - Chọn ngôn ngữ hỗ trợ, ta chọn Both Verilog and VHDL
  21. - chọn đối tượng hỗ trợ trong các thư viện, ta chọn All FPGA Family - Chọn các thư viện mô phỏng, ở đây ta chọn tất cảc các thư viện.
  22. - Chọn nơi chứa các file thư viện là ngầm định, sau đó Click Launch compile process
  23. - Quá trình biên dịch có thể nhiều thời gian, khi kết thúc sẽ có thông báo về kết quả và các lỗi phát sinh nếu có: 2 Tạo Project và mã nguồn VHDL Phần dưới đây hướng dẫn sử dụng chương trình bằng một ví dụ hết sức đơn giản là viết khối điều khiển các 8-led có sẵn ở trên mạch FPGA bằng các 8- Switch tương ứng. Sau khi khởi động phần mềm Xilinx ISE (ở đây dùng phiên bản 11.1), chọn File -> New Project. Đặt tên project là sp3_led (tên có thể đặt tùy {). Đồng thời, chọn mục Top-level source type là HDL để thiết kế bằng ngôn ngữ mô tả phần cứng.
  24. Tiếp theo, chọn NEXT để sang cửa sổ thiết lập các thuộc tính cho project, ở đây ta phải chọn đúng tên, gói (package), và tốc độ cho FPGA mà chúng ta muốn nạp, những thông tin này ghi trên mặt trên của chip FPGA. Cụ thể đối với Kit của chúng ta sẽ chọn Spartan 3E, gói PQ208 và Speed bằng -4. Ngầm định thì chương trình dùng để mô phỏng kiểm tra sẽ là Modelsim SE. Đối với ô Prefer Language ta chọn là VHDL.
  25. Sau đó click NEXT chương trình sẽ hỏi ta có muốn tạo mã nguồn mới không, chọn New source điền tên File là sp3_led và chọn kiểu là VHDL module.
  26. Hình 3.49. New source Wizard Tiếp theo sẽ là hộp thoại cho phép chúng ta tạo một file mô tả bằng cách khai báo cổng vào ra bằng giao diện đồ họa, ta bỏ qua bước này, chương trình sẽ tạo ra một file VHDL có tên sp3_led.vhd không chứa khai báo cổng, khai báo này ta có thể làm sau trong trình soạn thảo. Hình 3.49. New source Wizard Trong trường hợp nguồn chúng ta đã có sẵn chọn NEXT để chuyển sang hộp thoại bổ xung file có sẵn Add Source, chọn Add source nếu chúng ta muốn bổ xung một file có sẵn vào project.
  27. Hình 3.49. Thêm file mô tả VHDL Chú ý là cả hai bước trên đều có thể bỏ qua và chúng ta có thể tạo mới, hay bổ xung file vào project bất cứ lúc nào sau khi đã tạo xong project. Project Summary. Chọn Finish để ISE tạo ra một project mới với các thuộc tính như trên (hình 6).
  28. Hình 3.50. Project sumary Sau khi tạo Project thành công, chương trình chuyển sang chế độ làm việc với Project, Có 4 cửa sổ chính bao gồm - Design: Chứa sơ đồ cấu trúc của các module project bao gồm mã nguồn, các file constraint nếu có và các file khác. - Process: Nơi thực hiện các thao tác của quy trình thiết kế FPGA. - View/Editor là cửa sổ làm việc chính, nơi có thể chỉnh sửa file nguồn, xem thông tin tổng hợp vvv - Command line (Console): Là cửa sổ hỗ trợ dòng lệnh trực tiếp (giống cửa sổ TCL script trong ModelSim) Từ cửa sổ chương trình ta nhấp chuột đúp vào file sp3_led.vhd thuộc cửa sổ Design (phía góc trái trên) để bắt đầu tiến hành soạn thảo mã nguồn.
  29. Hình 3.51. Project Windows Sửa mã nguồn lại với nội dung như sau. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Uncomment the following library declaration if instantiating any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity sp3_led is Port ( SW1 : in STD_LOGIC; SW2 : in STD_LOGIC; SW3 : in STD_LOGIC; SW4 : in STD_LOGIC; SW5 : in STD_LOGIC; SW6 : in STD_LOGIC; SW7 : in STD_LOGIC; SW8 : in STD_LOGIC; LED1 : out STD_LOGIC;
  30. LED2 : out STD_LOGIC; LED3 : out STD_LOGIC; LED4 : out STD_LOGIC; LED5 : out STD_LOGIC; LED6 : out STD_LOGIC; LED7 : out STD_LOGIC; LED8 : out STD_LOGIC); end sp3_led; architecture Behavioral of sp3_led is begin LED1 <= not SW1; LED2 <= not SW2; LED3 <= not SW3; LED4 <= not SW4; LED5 <= not SW5; LED6 <= not SW6; LED7 <= not SW7; LED8 <= not SW8; end Behavioral; 3 Mô phỏng kiểm tra chức năng thiết kế. Để mô phỏng thiết kế ở cửa sổ Design chọn Behavioral Simulation sau đó chọn module cần kiểm tra ví dụ trong trường hợp này chúng ta chỉ có duy nhất module sp3_led. Kích đúp chuột vào biểu tượng Simulate Behavioral Model ở cửa sổ Process chương trình sẽ gọi Modelsim để chạy mô phỏng module tương ứng.
  31. Người sử dụng có thể làm theo cách truyền thống là mô phỏng bằng Modelsim mà không nhất thiết phải gọi từ Xilinx ISE. Để đơn giản và thống nhất từ bây giờ về sau các động tác kiểm tra ta đều làm theo phương pháp truyền thống là chạy riêng Modelsim mà không cần gọi từ ISE. 4 Tổng hợp thiết kế 4.1 Check syntax Tại cửa sổ Process, ấn chuột mở rộng quá trình Synthesis – XST và chọn Check Syntax. Chương trình kích hoạt khối kiểm tra cú pháp, thông thường nếu chúng ta đã làm mô phỏng kiểm tra chức năng ở bước 4.2 thì ở bược này không thể phát sinh lỗi. Kết quả thông báo ở cửa sổ Command line
  32. 4.1 Synthesis Click đúp chuột vào Synthesis –XST để kích hoạt trình tổng hợp thiết kế XST (Xilinx Synthesis Technology). Kết quả của quá trình tổng hợp thông báo ở cửa sổ Command Line.
  33. 4.3. Đọc kết quả tổng hợp. Tại cửa sổ làm việc chính (View/Editor) chọn Tab Design Summary sau đó chọn Symmary, Click chuột vào Synthesis Report để hiển thị file text chứa thông tin kết quả tổng hợp.
  34. Thiết kế của chúng ta chỉ gồm 8 cổng NOT vì vậy kết quả tổng hợp khá đơn giản, nội dung thu được có dạng sau: === * Final Report * === Final Results RTL Top Level Output File Name : sp3_led.ngr Top Level Output File Name : sp3_led Output Format : NGC Optimization Goal : Speed Keep Hierarchy : NO Design Statistics # IOs : 16 Cell Usage : # BELS : 8 # INV : 8 # IO Buffers : 16 # IBUF : 8 # OBUF : 8 === Device utilization summary: Selected Device : 3s500epq208-4 Number of Slices: 4 out of 4656 0%
  35. Number of 4 input LUTs: 8 out of 9312 0% Number of IOs: 16 Number of bonded IOBs: 16 out of 158 10% Partition Resource Summary: No Partitions were found in this design. === TIMING REPORT NOTE: THESE TIMING NUMBERS ARE ONLY A SYNTHESIS ESTIMATE. FOR ACCURATE TIMING INFORMATION PLEASE REFER TO THE TRACE REPORT GENERATED AFTER PLACE-and-ROUTE. Clock Information: No clock signals found in this design Asynchronous Control Signals Information: No asynchronous control signals found in this design Timing Summary: Speed Grade: -4 Minimum period: No path found Minimum input arrival time before clock: No path found Maximum output required time after clock: No path found Maximum combinational path delay: 6.034ns Timing Detail: All values displayed in nanoseconds (ns) === Timing constraint: Default path analysis Total number of paths / destination ports: 8 / 8 Delay: 6.034ns (Levels of Logic = 3) Source: SW1 (PAD) Destination: LED1 (PAD) Data Path: SW1 to LED1 Gate Net Cell:in->out fanout Delay Delay Logical Name (Net Name) IBUF:I->O 1 1.218 0.420 SW1_IBUF (SW1_IBUF) INV:I->O 1 0.704 0.420 LED11_INV_0 (LED1_OBUF) OBUF:I->O 3.272 LED1_OBUF (LED1) Total 6.034ns (5.194ns logic, 0.840ns route) (86.1% logic, 13.9% route) ===
  36. 4.4 Kết xuất sơ đồ công nghệ, và sơ đồ RTL (optional) Sơ đồ công nghệ và sơ đồ RTL có thể thu được bằng cách chọn tương ứng View Technology Schematic và View RTL Schematic. Sau đó chọn tất cả hoặc một phần Top Level Port bổ xung vào sơ đồ, chọn Create Schematic. Một sơ đồ cơ sở được tạo ra, để quan sát các đối tượng khác có thể click chuột vào các đối tượng hoặc kết nối trên đó để mở rộng hoặc chi tiết hóa sơ đồ. Sơ đồ công nghệ thu được như ở hình sau, làm tương tự như vậy để thu được sơ đồ RTL.
  37. 4.5. Kiểm tra thiết kế sau tổng hợp Để tạo ra file netlist phục vụ cho việc kiểm tra sau mô phỏng click vào Generate Post-synthesis simulation model như ở hình sau.
  38. Nếu quá trình tạo file thành công sẽ có thông báo tương ứng Process "Generate Post-Synthesis Simulation Model" completed successfully ở của sổ Command line. Sau đó mở thư mục nơi chứa các file của project ta sẽ thấy xuất hiện thư mục có tên netgen/synthesis có chứa file mô tả VHDL có tên sp3_led_synthesis.vhd. Nếu Modelsim đã hỗ trợ thiết kế trên thư viện UNISIM thì có thể tiến hành mô phỏng kiểm tra bình thường file nguồn này. Bước mô phỏng này nhằm khẳng định chức năng của mạch không bị thay đổi sau khi tổng hợp. Ở đây ta kiểm tra lại file netlist, kết quả như sau:
  39. 4.6. Gán chân vào ra sau tổng hợp Bước này làm nếu như chúng có Kit kiểm tra, trong trường hợp không có Kit thì không có thể bỏ qua bước này, chương trình sẽ tự động gán các chân vào ra của thiết kế cho các IO_pad bất kz của FPGA. Chương trình thực hiện gán chân là PlanAhead, để khởi động ta chọn lệnh IO planing (PlanAhead) – post synthesis trong cửa sổ Process mục User Constraint. Khi có cửa sổ PlanAhead thực hiện gán địa chỉ cho từng chân tương ứng của thiết kế, ví dụ như ở hình dưới đây ta gán chân P100 cho đầu ra LED2 như trên hình( Ở cửa sổ IO port chọn cổng LED2 sau khi điền chân vào ô site trên cửa sổ IO Properties chọn Apply) trên mạch tương ứng với các vị trí đèn led trên mạch FPGA. Tương tự như vậy ta gán các chân còn lại như sau: LED1 -> p102, LED2 -> p100, LED3 -> p99, LED4 -> p98, LED5 -> p97 LED6 -> p96, LED7 -> p94, LED8 -> p93, SW1 -> p160, SW2 -> p161, SW3 -> p162, SW4 -> p163, SW5 -> p164, SW6 -> p165, SW7 -> p167, SW8 -> p168
  40. Sau khi hoàn tất việc gán chân Save để lưu lại thông tin gán chân và đóng PlanAhead, quay trở lại với chương trình ISE. Thông tin gán chân được lưu ở trong một file text có tên là sp3_led.ucf. Khi mở file này bằng trình soạn thảo sẽ thấy nội dung trong file này như sau: #PACE: Start of PACE I/O Pin Assignments NET "LED1" LOC = "p102" ; NET "LED2" LOC = "p100" ; NET "LED3" LOC = "p99" ; NET "LED4" LOC = "p98" ; NET "LED5" LOC = "p97" ; NET "LED6" LOC = "p96" ; NET "LED7" LOC = "p94" ; NET "LED8" LOC = "p93" ; NET "SW1" LOC = "p160" ; NET "SW2" LOC = "p161" ; NET "SW3" LOC = "p162" ; NET "SW4" LOC = "p163" ; NET "SW5" LOC = "p164" ; NET "SW6" LOC = "p165" ; NET "SW7" LOC = "p167" ; NET "SW8" LOC = "p168" ;
  41. Một cách khác đơn giản hơn để gán chân là ta tạo một file UCF có tên trùng với tên module chính (sp3_led.ucf) và soạn thảo với nội dung như trên. 5 Hiện thực hóa thiết kế 5.1 Translate Để thực hiện Translate, chọn lệnh Translate, và nếu cần tạo file netlist sau Translate bằng lệnh tương ứng Generate Post-translate simulation model như ở hình dưới đây: Sau khi tạo file netlist thành công cũng sẽ có thông báo tương ứng ở cửa sổ dòng lệnh: Process "Generate Post-Translate Simulation Model" completed successfully. Nếu ta mở lại thư mục netgen sẽ thấy xuất hiện thêm thư mục con translate, file VHDL tương ứng sp3_led_translate.vhd là netlist tạo ra sau bước này, netlist này viết trên thư viện độc lập SIMPRIM. Ta cũng có thể tiến hành mô phỏng kiểm tra thiết kế sau translate giống bước mô phỏng kiểm tra sau Tổng hợp đã trình bày ở trên.
  42. 5.2 Mapping Để thực hiện quá trình Mapping chọn lệnh Map trong cửa sổ Process, quá trình sẽ được thực hiện tự động. Ở bước này chúng ta đã bắt đầu có thể kiểm tra các tham số về mặt thời gian đối với thiết kế, để thực hiện bước này (ngầm định khi Mapping bước này không thực hiện) chọn Analyze Post-map Static Timing như ở hình dưới đây Kết quả sẽ được hiện ra ở một file text tương ứng bên cửa sổ VIEW/EDITOR, đối với ví dụ này ta thu được bảng thời gian trễ như sau: Data Sheet report: All values displayed in nanoseconds (ns) Pad to Pad + + + Source Pad |Destination Pad| Delay | + + + SW1 |LED1 | 4.648| SW2 |LED2 | 4.648| SW3 |LED3 | 4.648| SW4 |LED4 | 4.648| SW5 |LED5 | 4.648|
  43. SW6 |LED6 | 4.648| SW7 |LED7 | 4.648| SW8 |LED8 | 4.648| + + + Sau khi maping cũng có thể tạo file netlist để mô phỏng kiểm tra chức năng bằng lệnh Generate Post-map simulation model tương tự như với các bước trên đã làm. 5.3 Routing Bước cuối cùng để sẵn sàng tạo ra file bitstrem để nạp vào FPGA.Ở bước này ta cũng thực hiện các bước cơ bản như đối với các bước đã liệt kê ở phần Mapping. Điểm khác biệt là ở đây kết quả Analyze về mặt thời gian là chính xác khi mà các khối đã thực sự kết nối với nhau. Kết quả về mặt thời gian thể hiện ở bảng sau: Data Sheet report: All values displayed in nanoseconds (ns) Pad to Pad + + + Source Pad |Destination Pad| Delay | + + +
  44. SW1 |LED1 | 5.095| SW2 |LED2 | 4.835| SW3 |LED3 | 4.835| SW4 |LED4 | 4.835| SW5 |LED5 | 4.835| SW6 |LED6 | 4.835| SW7 |LED7 | 4.818| SW8 |LED8 | 4.853| + + + 6. Tạo file cấu hình FPGA Để tạo file bitstream để cấu hình FPGA chọn lệnh Generate Programming File như hình dưới đây Sau quá trình này 1 file có tên sp3_led.bit được tạo ra trong thư mục chứa thiết kế. Thực hiện các bước sau để nạp cấu hình FPGA vào mạch thật. 7. Nạp cấu hình vào FPGA. Để nạp cấu hình vào file FPGA cần phải có kit FPGA thật được kết nối với máy tính bằng dây nạp JTAG (thông thường qua cổng LPT hoặc USB). Tại cửa sổ Process chọn Configure Target Device
  45. Lệnh này khởi tạo chương trình ISE imPACT, chương trình sẽ có thông báo về việc tạo file nạp cấu hình, nhấn OK bỏ qua hộp thoại này. Giao diện chương trình imPACT như ở dưới đây. Bên cửa sổ imPACT Flow chọn Boundary Scan. Click chuột phải bên cửa sổ chính chọn Initial Chain. Nếu thành công sẽ thấy xuất hiện biểu tượng FPGA và một khối ROM như ở hình dưới đây.
  46. Chương trình sẽ hỏi có muốn gán file cấu hình không chọn Yes.
  47. Tại cửa sổ này chọn file bitstream là sp3_led.bit, chọn Open. Hộp thoại tiếp theo chọn No Chương trình tiếp tục hỏi nạp cấu hình vào ROM, chọn Bypass, cấu hình sẽ được nạp vào FPGA trực tiếp. Cửa sổ tiếp theo thông báo về cấu hình đã chọn, ấn OK để tiếp tục quay trở về ISE imPACT, Click chuột vào biểu tượng Spartan FPGA và chọn lệnh Program trong cửa sổ imPACT Process.
  48. Chương trình tiến hành nạp cấu hình vào FPGA, nếu quá trình thành công sẽ có thông báo PROGRAM SUCCESSED và đèn DONE trên mạch FPGA sẽ sáng.
  49. Có thể kiểm tra trực tiếp trên mạch thiết kế bằng cách điều chỉnh các SWITCH và quan sát các LED tương ứng.
  50. Phụ lục 3: Thực hành tổng hợp trên thư viện cell chuẩn Trong phần này ta sẽ thực hành tổng hợp trên thư viện cổng chuẩn 90nm với một số module VHDL đơn giản, mục đích để làm quen với cách sử dụng chương trình cũng như các câu lệnh khi làm việc với chương trình Synopsys Design Compiler. 1 Bài toán cộng hai số thực Chúng ta sẽ sử dụng một phần thiết kế của bộ cộng số thực dấu phẩy động làm đối tượng tổng hợp. Để hiểu được ví dụ này cần nói qua về định dạng của số thực theo chuẩn IEEE 754 và phép toán trên đó. Định dạng của số thực dấu phẩy động 64-bit (double) thể hiện ở hình sau: Định dạng số thực 64-bit Giá trị của số biểu diễn tính bằng công thức: Trong đó: Bít trọng số cao nhất của 64 –bit sign biểu diễn dấu, nếu sign = 1 thì dấu âm, sign=0 thì dấu dương. 10 bit tiếp theo từ bít 62 đến 52 biểu diễn số mũ e (exponent), 10 bit này này biểu diễn các giá trị không dấu từ 0 đến 2047. Chuẩn số thực quy định giá trị thực biểu diễn thực chất bằng eA = e – 1023, giá trị 1023 gọi là độ dịch của số mũ (exponent bias) có nghĩa là miền giá trị của số mũ từ -1023 đến +1022
  51. 52 bít cuối cùng a51a50 a1a0 dùng để biểu diễn phần thập phân fraction với giá trị tương ứng là mA = 1, a51a50 a1a0 , số 1 trong công thức này không được biểu diễn trực tiếp nên còn gọi là bit ẩn. Để thực hiện phép cộng của hai số thực A, B với các giá trị như sau. Một trong những bước đầu tiên là quy đổi hai số về một một số mũ chung, theo lý thuyết thì phải biểu diễn hai số bằng số mũ của số lớn hơn, giả sử như ea>eb khi đó B được viết lại thành: Tiếp theo tiến hành cộng phần thập phân của hai số Nhận xét rằng phép nhân với 2-(ea-eb) thực chất là phép dịch logic sang bên phải giá trị bằng ea-eb. Để hoàn thành phép cộng còn phải tiến hành thêm một số bước nữa nhưng trong ví dụ minh họa này ta chỉ thể hiện hai pha đầu tiên của phép toán cộng như ở sơ đồ sau:
  52. A B Operand decomposition sa sb ea ea ma mb PHASE 1 Σ Compare_exponent e1 REG1 sa2 sb2 e2 ma2 mb2 Sel MUX Correct _exponent PHASE 2 mSH mNS shift_value shifter mShifted REG2 sa3 sb3 e3 ma3 mb3 Sơ đồ cấu trúc pha 1, 2 của bộ cộng số thực 64-bit Phase 1: Các toán hạng số thực 64-bit A, B đầu tiên được phân tách thành các thành phần gồm dấu, số mũ, và phần thập phân ở khối Operand decomposition. Khối tiếp theo sẽ tiến hành so sánh hai giá trị số mũ để quyết định xem giá trị thập phân của A hay của B sẽ bị dịch. Để so sánh ta sử dụng một bộ trừ exponent_compare. Kết quả của phép trừ e1 cùng với các giá trị mA, mB, sA, sB được lưu ở thanh ghi trung gian REG1 trước khi chuyển sang bước xử lý kế tiếp. Thanh ghi trung gian có tác dụng pipelined hóa cấu trúc nhằm tăng tốc cho khối xử lý. Phase 2: Theo ngầm định ta sẽ lấy e1 = ea-eb, e2 là kết quả e1 được lưu vào REG1, nếu kết quả là không âm thì ea >= eb, tiến hành dịch mB. Nếu kết quả là âm thì ea < eb, khi đó mA sẽ bị dịch, trên sơ đồ bit dấu Sel được sử dụng để điều khiển multiplexer MUX thực hiện phép chọn này.
  53. Số lượng bít bị dịch shift_value tương ứng giá trị bằng trị tuyệt đối của e2, giá trị đó bằng e2 nếu e2>=0 và bằng bù 2 của e2 nếu e2<0, khối correct_exponent sẽ thực hiện nhiệm vụ này. Khối shifter thực hiện động tác dịch với đầu vào là mSH và shift_value. Kết quả đưa ra của bộ dịch là một chuỗi 54 bít. Kết thúc pha này các giá trị trung gian shift_value, mShifted, mNS, sA, sB tiếp tục được lưu vào thanh ghi REG2 để chuyển sang bước xử lý thứ ba. Mã nguồn của từng khối liệt kê như ở dưới đây. Khối operand decomposition: FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity fpu_operand_decomposition is port( A : in std_logic_vector(63 downto 0); B : in std_logic_vector(63 downto 0); eA : out std_logic_vector(10 downto 0); eB : out std_logic_vector(10 downto 0); mA : out std_logic_vector(51 downto 0); mB : out std_logic_vector(51 downto 0); sA : out std_logic; sB : out std_logic ); end fpu_operand_decomposition; architecture rtl of fpu_operand_decomposition is begin sA <= A(63); sB <= B(63); eA <= A(62 downto 52); eB <= B(62 downto 52); mA <= A(51 downto 0); mB <= B(51 downto 0); end rtl; Khối so sánh exponent_compare:
  54. FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fpu_exponent_compare is port( eA : in std_logic_vector(10 downto 0); eB : in std_logic_vector(10 downto 0); e1 : out std_logic_vector(11 downto 0) ); end fpu_exponent_compare; architecture rtl of fpu_exponent_compare is signal sum_temp: std_logic_vector(11 downto 0); signal a_temp: std_logic_vector(11 downto 0); signal b_temp0: std_logic_vector(11 downto 0); signal b_temp: std_logic_vector(11 downto 0); signal CI: std_logic; begin a_temp <= '0' & eA; b_temp0 <= '0' & eB; b_temp <= not b_temp0; CI <= '1'; minus: process (a_temp, b_temp, CI) begin sum_temp <= a_temp + b_temp + CI; end process minus; e1 <= sum_temp(11 downto 0); end rtl; Khối thanh ghi REG1: FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL;
  55. entity fpu_reg1 is port( clk : in std_logic; sA, sB : in std_logic; e1 : in std_logic_vector(11 downto 0); mA, mB : in std_logic_vector(51 downto 0); sA2, sB2 : out std_logic; mA2, mB2 : out std_logic_vector(51 downto 0); e2 : out std_logic_vector(11 downto 0) ); end fpu_reg1; architecture rtl of fpu_reg1 is begin reg: process (clk) begin if clk = '1' and clk'event then sa2 <= sa; sb2 <= sb; mA2 <= ma; mb2 <= mb; e2 <= e1; end if; end process reg; end rtl; Khối MUX: FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity fpu_mux is port( Sel : in std_logic; mA2 : in std_logic_vector(51 downto 0); mB2 : in std_logic_vector(51 downto 0); mSh : out std_logic_vector(51 downto 0); mNS : out std_logic_vector(51 downto 0) ); end fpu_mux; architecture rtl of fpu_mux is begin
  56. selm: process (Sel, ma2, mb2) begin if Sel = '1' then mSh <= mb2; mNS <= ma2; else mSh <= ma2; mNS <= mb2; end if; end process selm; end rtl; Khối dịch shifter: FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity fpu_shifter is port( mSh : in std_logic_vector(51 downto 0); shift_value: in std_logic_vector(10 downto 0); mShifted : out std_logic_vector(53 downto 0) ); end fpu_shifter; architecture rtl of fpu_shifter is signal shift5: std_logic_vector(53 downto 0); signal shift4: std_logic_vector(53 downto 0); signal shift3: std_logic_vector(53 downto 0); signal shift2: std_logic_vector(53 downto 0); signal shift1: std_logic_vector(53 downto 0); signal shift0: std_logic_vector(53 downto 0); signal shift_in: std_logic_vector(53 downto 0); signal sa : integer; signal null_shift :std_logic; begin shift_in <= mSh & "00"; null_shift <= shift_value(10) or shift_value(9) or shift_value(8) or shift_value(7) or shift_value(6);
  57. with shift_value(5) select shift5 '0') when '1', shift0 when others; end rtl; Khối correct_exponent: FPU ADDER 64 VTDT - KTVXL library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fpu_correct_exponent is port( e2 : in std_logic_vector(11 downto 0); shift_value : out std_logic_vector(10 downto 0) ); end fpu_correct_exponent; architecture rtl of fpu_correct_exponent is signal shout0 : std_logic_vector(11 downto 0); signal shout : std_logic_vector(11 downto 0); begin shout0 <= not e2;
  58. shout <= shout0 + 1; process (e2, shout) begin if e2(11) = '1' then shift_value <= shout(10 downto 0); else shift_value <= e2(10 downto 0); end if; end process; end rtl; 2 Thiết lập cài đặt thư viện. Người thiết kế có thể lựa chọn các phương pháp khác nhau để tổ chức các file dữ liệu vào ra cho quá trình tổng hợp, theo cách thông thường thì các file phục vụ tổng hợp được tổ chức như ở hình sau: Trong đó lần lượt từ trên xuống dưới, db là thư mục chứa kết quả ra của quá trình tổng hợp có dạng .db, log chứa các file mô tả kết quả tổng hợp dưới dạng văn bản, thường có đuôi mở rộng là .rpt, netlist là thư mục chứa các mô tả netlist sau tổng hợp của thiết kế, scr là thư mục chứa các file văn bản mô tả các điều kiện ràng buộc cho tổng hợp hay còn gọi là constraint files, các file này thường có phần duôi mở rộng là .scr (script), thư mục src là thư mục chứa các file nguồn mô tả RTL của thiết kế, đôi khi thư mục này được đặt là RTL. Chúng ta thấy ngoài các thư mục trên thì còn một file có tên là .synopsys_dc_setup là một file đặc biệt dùng để cài đặt các tham số dùng chung cho Design compiler. Một trong những nhiệm vụ quan trọng của file này là cài đặt thư viện mà trên đó sẽ tiến hành tổng hợp. Ví dụ nội dung một file cài đặt đó như sau: # Define the target technology library, symbol library,
  59. # and link libraries set target_library /root/umc_libs/ll/fsc0h_d_sc_wc.db set symbol_library /root/umc_libs/ll/fsc0h_d_sc.sdb set link_library [concat $target_library "*"] set search_path [concat $search_path ./src] set designer "Kien Quang" set company "HVKTQS, VXL." # Define path directories for file locations set source_path "./src/" set script_path "./scr/" set log_path "./log/" set db_path "./db/" set netlist_path "./netlist/" Trong đó các dòng bắt đầu bằng dâu # là dòng chú thích, đặc biệt chú ý hai lệnh đầu tiên là set target_library và set symbol_library dùng để chỉ tới file thư viện tương ứng, các file thư viện phải do công ty cung cấp thư viện chuyển giao cho bộ phận thiết kế. Trong trường hợp này các file thư viện gồm fsc0h_d_sc_wc.db và fsc0h_d_sc.sdb được đặt trong thư mục tương ứng là /root/umc_libs/ll/. Các dòng lệnh bên dưới thiết lập một số biến dùng chung cho quá trình tổng hợp. File cài đặt .synopsys_dc_setup có thể được tạo ra bằng trình soạn thảo bất kz và copy vào trong thư mục nơi chứa thiết kế như trên. Sau khi đã được cài đặt Design compiler khởi động từ trong cửa sổ console của Linux bằng lệnh dc_shell.
  60. Chương trình Synopsys design compiler Về thực chất các dòng lệnh chứa trong file .synopsys_dc_setup sẽ tự động chạy mỗi khi Design Compiler được khởi động. 2. Đọc file mô tả RTL. Để đọc các file mô tả VHDL, ta đọc lần lượt các file mô tả khối con bằng lệnh analyze, sau đó đọc mô tả cấp cao nhất bằng lệnh read: analyze -f VHDL src/fpu_adder_decomposition.vhd analyze -f VHDL src/fpu_exponent_compare.vhd analyze -f VHDL src/fpu_reg1.vhd analyze -f VHDL src/fpu_mux.vhd analyze -f VHDL src/fpu_correct_exponent.vhd analyze -f VHDL src/fpu_shifter.vhd analyze -f VHDL src/fpu_reg2.vhd read -f VHDL src/fpu_adder_phase12.vhd Các lệnh trên có thể được gõ trực tiếp vào cửa sổ dòng lệnh của Design compiler sau khi đã khởi động ở bước 2. Cách thứ hai thường được sử dụng đó là lưu toàn bộ vào một file text ví dụ vào file có tên read_design.scr lưu vào thư mục scr, sau đó tại cửa sổ dòng lệnh ta thực hiện lệnh sau.
  61. include scr/read_design.scr Lệnh này sẽ đọc tất cả các dòng lệnh có trong read_design.scr và thực hiện lần lượt Nếu quá trình đọc không có lỗi sẽ thu được kết quả như sau: 3 Tổng hợp thiết kế. Để biên dịch thiết kế dùng lệnh compile, trước đó ta phải dùng lệnh curent_design để xác định thiết kế nào sẽ tổng hợp: current_design fpu_adder_phase12 compile Chương trình tổng hợp được kích hoạt, chương trình này sẽ phân tích mã VHDL và đọc thông tin thư viện để tổng hợp nên mạch. Vì tạm thời ở bước này chúng ta không đặt các điều kiện, yêu cầu ràng buộc nên chương trình tổng hợp không có căn cứ để tối ưu hóa và chạy rất nhanh, tuy nhiên, kết quả tổng hợp đưa ra là rất kém.
  62. 4. Đọc kết quả tổng hợp sơ bộ. Lệnh report trong Design compiler dùng để thống kê kết quả tổng hợp, lệnh này có rất nhiều cú pháp cho chúng ta thống kê nhiều thông tin khác nhau, kết quả có thể in trực tiếp ra màn hình hoặc lưu vào file. Dưới đây ta lấy ví dụ thống kê thông tin về diện tích và thời gian trễ của mạch. dc_shell> report_area Kết quả tổng hợp về mặt diện tích như sau: Report : area Design : fpu_adder_phase12 Version: V-2004.06-SP1 Date : Tue Apr 6 22:11:10 2010 Library(s) Used: fsc0h_d_sc_wc (File: /root/umc_libs/ll/fsc0h_d_sc_wc.db) Number of ports: 248 Number of nets: 675 Number of cells: 7 Number of references: 7
  63. Combinational area: 3675.000000 Noncombinational area: 4741.000000 Net Interconnect area: undefined (Wire load has zero net area) Total cell area: 8416.000000 Thời gian trễ, sử dụng lênh report_timing, theo trên sơ đồ khu vực gây trễ lớn nhất nằm ở khối corect_exponent sau đó qua shiffter, ta dùng lệnh sau để quan sát một trong những đường gây trễ đó: dc_shell> report_timing -from 'u3/e2[0] Thu được kết quả như sau: Performing report_timing on pin 'u3/e2[0]'. Startpoint: u3/e2_reg[0] (rising edge-triggered flip-flop) Endpoint: u7/mA3_reg[30] (rising edge-triggered flip-flop) Point Incr Path u3/e2_reg[0]/CK (QDFFEHD) 0.00 0.00 r u3/e2_reg[0]/Q (QDFFEHD) 0.23 0.23 f u3/e2[0] (fpu_reg1) <- 0.00 0.23 f u5/e2[0] (fpu_correct_exponent) 0.00 0.23 f u5/U40/O (INVCHD) 0.12 0.34 r u5/add_24/plus/plus/A[0] (fpu_correct_exponent_DW01_inc_11_0) 0.00 0.34 r u5/add_24/plus/plus/U1_1_1/C (HA1EHD) 0.13 0.47 r u5/add_24/plus/plus/U1_1_2/C (HA1EHD) 0.11 0.58 r u5/add_24/plus/plus/U1_1_3/C (HA1EHD) 0.11 0.69 r u5/add_24/plus/plus/U1_1_4/C (HA1EHD) 0.11 0.79 r u5/add_24/plus/plus/U1_1_5/C (HA1EHD) 0.11 0.90 r u5/add_24/plus/plus/U1_1_6/C (HA1EHD) 0.11 1.01 r u5/add_24/plus/plus/U1_1_7/C (HA1EHD) 0.11 1.12 r u5/add_24/plus/plus/U1_1_8/C (HA1EHD) 0.11 1.23 r u5/add_24/plus/plus/U1_1_9/S (HA1EHD) 0.16 1.39 f u5/add_24/plus/plus/SUM[9] fpu_correct_exponent_DW01_inc_11_0) 0.00 1.39 f u5/U41/O (MUX2CHD) 0.19 1.58 f u5/shift_value[9] (fpu_correct_exponent) 0.00 1.58 f u6/shift_value[9] (fpu_shifter) 0.00 1.58 f u6/U666/O (NR3BHD) 0.13 1.71 r
  64. u6/U665/O (AN3B2BHD) 0.28 1.99 r u6/U663/O (ND3CHD) 0.65 2.64 f u6/U662/O (INVCHD) 0.91 3.55 r u6/U497/O (ND2CHD) 0.44 3.99 f u6/U496/O (INVCHD) 0.49 4.48 r u6/U480/O (AOI22BHD) 0.15 4.63 f u6/U479/O (OAI112BHD) 0.14 4.78 r u6/mShifted[30] (fpu_shifter) 0.00 4.78 r u7/mShifted[30] (fpu_reg2) 0.00 4.78 r u7/mA3_reg[30]/D (QDFFEHD) 0.00 4.78 r data arrival time 4.78 Kết quả này cho phép ta ước lượng một cách tương đối xung nhịp hệ thống có chu kz Tclk ~ 4,78 ns 5. Tối ưu hóa thiết kế, xuất kết quả và netlist Với kết quả sơ bộ như trên có thể sử dụng các lệnh giới thiệu ở phần 4 để tiến hành biên tổng hợp mạch với điều kiện ràng buộc. Tạo file có tên default.con với nội dung như sau: /* Define clock for PIPE1 */ clk_period = 1.6 /* Create real clock if clock port is found */ if (find(port, clk) == {"clk"}) { clk_name = clk create_clock -period clk_period clk } set_clock_uncertainty 0.1 clk_name set_operating_conditions -max WCCOM -max_library fsc0h_d_sc_wc auto_wire_load_selection = true set_driving_cell -lib_cell BUFHHD all_inputs() set_wire_load_mode enclosed /*set_max_fanout 6.0 all_inputs()*/ /* Define timming_constraints */ set_input_delay 0.35 -clock clk_name all_inputs() set_output_delay 0.35 -clock clk_name all_outputs() set_max_capacitance 0.03 all_inputs() set_load 0.01 all_outputs() set_max_transition 0.2 all_inputs() set_max_area 7000
  65. File này thiết lập các điều kiện ràng buộc về trong đó cần chú { là điều kiện về xung nhịp hệ thống và diện tích, ở đây chúng ta đặt chu kz xung nhịp là 1.6 ns, và diện tích là 7000. Sau khi có file này ta tiến hành tổng hợp thiết kế có điều kiện ràng buộc. Thực hiện tổng hợp lại từ đầu, đầu tiên đọc thiết kế : include scr/read_design.scr Sau đó gán các điều kiện ràng buộc cho thiết kế include scr/default.con Thực hiện tổng hợp: compile –effort medium Quá trình tổng hợp lần này thực hiện sẽ thực hiện lâu hơn trước, để thống kê đầy đủ tự động kết quả đầu ra ta soạn một file report.scr có nội dung như sau: /* writing the results */ filename = "fpu_adder_phase12" rpt_file = filename + ".rpt" write -f db -hierarchy -o db_path + filename + ".db" write -f verilog -hier -o back_source_path + filename + ".v" write -f vhdl -hier -o back_source_path + filename + ".vhd" maxpaths = 4 report_timing -from u3/e2[0] > log_path + rpt_file report_timing -max_path maxpaths -cap -net > log_path + rpt_file report_area >> log_path + rpt_file report_design >> log_path + rpt_file report_cell >> log_path + rpt_file check_design >> log_path + rpt_file Kết quả tổng hợp bao gồm file fpu_adder_phase12.db được lưu vào thư mục db, file netlist fpu_adder_phase12.vhd được lưu trong thư mục netlist. Và file mô tả chi tiết kết quả tổng hợp fpu_adder_phase12.rpt lưu trong thư mục log Dưới đây trích những thông tin quan trọng từ bản tổng hợp đó: Thông tin về mặt thời gian: Design : fpu_adder_phase12 Version: V-2004.06-SP1 Startpoint: u3/e2_reg[0] (rising edge-triggered flip-flop clocked by clk)
  66. Endpoint: u7/mA3_reg[2] (rising edge-triggered flip-flop clocked by clk) Path Group: clk Path Type: max Des/Clust/Port Wire Load Model Library fpu_adder_phase12 enG5K fsc0h_d_sc_wc fpu_correct_exponent enG5K fsc0h_d_sc_wc fpu_correct_exponent_DW01_inc_11_1 enG5K fsc0h_d_sc_wc fpu_shifter enG5K fsc0h_d_sc_wc Point Fanout Cap Incr Path clock clk (rise edge) 0.00 0.00 clock network delay (ideal) 0.00 0.00 u3/e2_reg[0]/CK (QDFFKHD) 0.00 0.00 r u3/e2_reg[0]/Q (QDFFKHD) 0.22 0.22 f u3/e2[0] (net) 2 0.02 0.00 0.22 f u3/e2[0] (fpu_reg1) 0.00 0.22 f e2[0] (net) 0.02 0.00 0.22 f u5/e2[0] (fpu_correct_exponent) 0.00 0.22 f u5/e2[0] (net) 0.02 0.00 0.22 f u5/U64/O (INVKHD) 0.05 0.27 r u5/shout0[0] (net) 4 0.02 0.00 0.27 r u5/add_24/plus/plus/A[0] (fpu_correct_exponent_DW01_inc_11_1) 0.00 0.27 r u5/add_24/plus/plus/A[0] (net)0.02 0.00 0.27 r u5/add_24/plus/plus/U16/O (ND2HHD) 0.08 0.34 f u5/add_24/plus/plus/n61 (net) 2 0.02 0.00 0.34 f u5/add_24/plus/plus/U44/O (NR2IHD) 0.08 0.42 r u5/add_24/plus/plus/n71 (net) 2 0.02 0.00 0.42 r u5/add_24/plus/plus/U5/O (INVKHD) 0.03 0.45 f u5/add_24/plus/plus/n55 (net) 1 0.01 0.00 0.45 f u5/add_24/plus/plus/U27/O (ND2KHD) 0.03 0.49 r u5/add_24/plus/plus/n56 (net) 1 0.01 0.00 0.49 r u5/add_24/plus/plus/U33/O (ND2HHD) 0.04 0.52 f u5/add_24/plus/plus/SUM[4] (net) 1 0.01 0.00 0.52 f u5/add_24/plus/plus/SUM[4] (fpu_correct_exponent_DW01_inc_11_1) 0.00 0.52 f u5/shout[4] (net) 0.01 0.00 0.52 f u5/U56/O(ND2HHD) 0.04 0.57 r u5/n77 (net) 1 0.01 0.00 0.57 r
  67. u5/U52/O (ND2HHD) 0.06 0.63 f u5/shift_value[4] (net) 0.02 0.00 0.63 f u5/shift_value[4] (fpu_correct_exponent)0.00 0.63 f shift_value[4] (net) 0.02 0.00 0.63 f u6/shift_value[4] (fpu_shifter) 0.00 0.63 f u6/shift_value[4] (net) 0.02 0.00 0.63 f u6/U1139/O (INVKHD) 0.06 0.69 r u6/n1199 (net) 0.02 0.00 0.69 r u6/U1278/O (INVKHD) 0.03 0.72 f u6/n1198 (net) 2 0.02 0.00 0.72 f u6/U674/O (INVKHD) 0.04 0.76 r u6/n527 (net) 2 0.01 0.00 0.76 r u6/U811/O (NR2GHD) 0.06 0.81 f u6/n526 (net) 3 0.02 0.00 0.81 f u6/U723/O (INVDHD) 0.11 0.92 r u6/n973 (net) 3 0.01 0.00 0.92 r u6/U390/O (NR2BHD) 0.07 1.00 f u6/n1165 (net) 1 0.00 0.00 1.00 f u6/U725/OB (MXL2CHD) 0.17 1.16 r u6/n1164 (net) 1 0.01 0.00 1.16 r u6/U935/O (ND2HHD) 0.07 1.24 f u6/n618 (net) 2 0.01 0.00 1.24 f u6/U806/O (ND2HHD) 0.06 1.30 r u6/n831 (net) 2 0.01 0.00 1.30 r u6/U1205/O (ND2HHD) 0.05 1.35 f u6/n829 (net) 1 0.00 0.00 1.35 f u6/U1204/O (MAOI1CHD) 0.11 1.46 r u6/n823 (net) 1 0.00 0.00 1.46 r u6/U1090/O (ND2CHD) 0.05 1.51 f u6/mShifted[2] (net)1 0.00 0.00 1.51 f u6/mShifted[2] (fpu_shifter) 0.00 1.51 f mShifted[2] (net) 0.00 0.00 1.51 f u7/mShifted[2] (fpu_reg2) 0.00 1.51 f u7/mShifted[2] (net) 0.00 0.00 1.51 f u7/mA3_reg[2]/D (DFFCHD) 0.00 1.51 f data arrival time 1.51 clock clk (rise edge) 1.60 1.60 clock network delay (ideal) 0.00 1.60 clock uncertainty -0.10 1.50 u7/mA3_reg[2]/CK (DFFCHD) 0.00 1.50 r library setup time -0.14 1.36 data required time 1.36 data required time 1.36 data arrival time -1.51 slack (VIOLATED) -0.16 Thông tin về mặt diện tích: Report : area
  68. Design : fpu_adder_phase12 Version: V-2004.06-SP1 Library(s) Used: fsc0h_d_sc_wc (File: /root/umc_libs/ll/fsc0h_d_sc_wc.db) Number of ports: 248 Number of nets: 682 Number of cells: 14 Number of references: 8 Combinational area: 7904.000000 Noncombinational area: 4832.000000 Total cell area: 12736.000000 Có thể nhận xét rằng về mặt diện tích tăng lên đáng kể so với lần tổng hợp không có constraint nhưng về thời gian thì tham số thời gian đã có cải thiện đáng kể. Từ mức trễ 4.78 ns xuống còn 1,7 ns. Có thể tiếp tục tối ưu hóa thiết kế dùng các một trong các sơ đồ tổng hợp ở phần 4.2 chương IV để thu được các kết quả tốt hơn.
  69. Tài liệu tham khảo 1. Thiết kế mạch bằng máy tính – Nguyễn Linh Giang NXB Khoa học kỹ thuật 2005 2. Thiết kế logic mạch số - Nguyễn Thúy Vân, NXB Khoa học kỹ thuật 2005 3. Kỹ thuật số - Lê Xuân Bằng NXB Khoa học kỹ thuật 4. Balch M.Complete digital design.A comprehensive guide to digital electronics and computer system architecture.2003 5. The Definitive Guide to How Computers Do Math (Maxfield, Brawn, 2005) 6. Wakerly J.F.Digital design principles and practices.1999 7. IEEE Standard for Binary Floating-Point Arithmetic. ANSI/IEEE Standard No. 754. American National Standards Institute. –Washington, DC, 1985. 8. Ercegovac M., Lang T. Digital Arithmetic: -San Francisco, Morgan Kaufmann Publishers, 2004. -709 с. 9. VHDL standard reference IEEE 2002. 10. Synopsys User Guide Design Compiler 11. Advanced ASIC Chip Synthesis Using Synopsys Design Compiler Physical Compiler And Primetime.Bhatn 12. The VLSI Handbook, 2Ed 13. Algorithms for VLSI Physical Design Automation, 3rd Edition 14. Computer Organization and Design,Third Edition 15. Computers - VHDL Programming by Example (McGraw Hill - 4th Ed) 16. Digital Design with VHDL (Limaye) 17. FPGA_Advantage_and_CoreGen_VHDL 18. Hwang Microprocessor Design. Principles and Practices with VHDL 19. Kluwer Academic - Vhdl A Logic Synthesis Approach 20. McGraw.Hill.VHDL.Programming.by.Example.4th.Ed 21. Spartan3E description from Xilinx (DS312.pdf, ug331.pdf) 22. Mips Instruction Set Reference Vol I 23. 24. 25. 26. 27.
  70. 28. 29. 30. 31.