Sổ tay lập trình VHDL

Các thành phần chính xây dựng trong ngôn ngữ VHDLđược chia ra

thành năm nhóm cơ bảnnhư sau:

- Entit y

- Architecture

- Package

- Configuration.

-Library.

Entity: Trong một hệ thống số, thông thườngđược thiết kế theo một sự

xếp chồng các modul, mà mỗi Modul nàytương ứng với một thực thể thiết

kế (Đượcgọi là Entity ) trong VHDL. Mỗi một Ent ity bao gồmhaiphần :

- Khaibáo thực thể ( Entity).

- Thân kiến trúc ( Architecture Bodies )

Một khai báo Entityđược dùng để mô tả giao tiếp bên ngoài của một

phần tử(component), nó bao gồm các khai báo các cổng đầu vào, các cổng

đầu ra của phần tử đó. Phần thân của kiến trúcđược dùng để mô tả sự thực

hiện bên trong của thực thể đó.

pdf87 trang | Chia sẻ: NamTDH | Lượt xem: 1333 | Lượt tải: 0download
Bạn đang xem trước 20 trang nội dung tài liệu Sổ tay lập trình VHDL, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
gin {sequential_statement} end [identifier]; Identifier được sử dụng để chỉ ra tên của procedure và interface_list chỉ ra các tham số hình thức của procedure. Mỗi tham số được sử dụng theo định nghĩa sau: [class] name_list [mode] type_name [:=expression]; Class của đối tượng được xem như hằng, biến , hoặc là tín hiệu và mode của đối tượng có thể là in, out , inout. Nếu không có mode được chỉ ra thì tham số được hiểu như mode in, nếu không có class được chỉ ra thì các tham số mode in được hiểu như là các hằng, còn tham số mode out và inout được hiểu như là các biến. Các tham số có thể là các hằng, các biến, hoặc các tín hiệu và mode của chúng có thể là in, out, hoặc inout. Nếu lớp của các tham số không xác định rõ ràng thì mặc nhiên nó là constant, nếu nó là mode in, còn nó là biến nếu mode của tham số đó là out hoặc inout. Một ví dụ thân procedure mô tả hành vi hoạt động của các đơn vị logic số học như sau : type OP_CODE is ( ADD, SUB, MUL, DIV, LT, LE, EQ); … procedure ARITH_UNIT (A, B : in INTEGER ; OP : in OP_CODE ; Z : out INTEGER; ZCOMP : out BOOLEAN ) is begin case OP is when ADD => Z := A+B; when SUB => Z := A-B; when MUL => Z := A*B; when DIV => Z := A/B; when LT => ZCOMP := A<B; when LE => ZCOMP := A<=B; when EQ => ZCOMP := A=B; end case ; end ARITH_UNIT; Ta xem một ví dụ khác của thân một procedure, procedure này quay véc tơ đã được xác định với tên là ARRAY_NAME, bắt đầu từ bit START_BIT tới bit STOP_BIT, bởi một giá trị ROTATE_BY. Lớp đối tượng của tham số ARRAY_NAME được xác định một cách tường minh. Biến FILL_VALUE tự động được khởi tạo về ‘0’ mỗi khi procedure được gọi. Procedure ROTATE_LEFT (signal ARRAY_NAME : inout Bit_vector ; START_BIT, STOP_BIT : in NATUAL; ROTATE_BY : in POSITIVE ) is Variable FILL_VALUE : BIT; begin assert STOP_BIT > START_BIT report “STOP_BIT is not greater than START_BIT” severity NOTE; for MACVAR3 in 1 to ROTATE_BY loop FILL_VALUE := ARRAY_NAME (STOP_BIT); for MACVAR1 in STOP_BIT downto (START_BIT + 1) loop ARRAY_NAME (MACVAR1) <= ARRAY_NAME (MACVAR1 –1); end loop; ARRAY_NAME (START_BIT) <= FILL_VALUE ; end loop; end procedure ROTATE_LEFT; Các procedure được gọi bởi lời gọi procedure. Một lời gọi Procedure có thể là một phát biểu tuần tự hoặc một phát biểu đồng thời, phát biểu này phụ thuộc vào nơi xuất hiện lời gọi thủ tục hiện tại. Nếu lời gọi này nằm bên trong một phát biểu process hoặc một chương trình con khác thì nó được gọi là phát biểu gọi procedure tuần tự, ngược lại nó được gọi là phát biểu gọi procedure gọi đồng thời. Cú pháp của phát biểu gọi procedure như sau : [ label : ] procedure_name ( list_of_actual ); Thực tế các biểu thức, các biến, các tín hiệu hoặc các file, được chuyển vào trong thủ tục và các tên cuả đối tượng và các tên này sẽ được dùng để lấy các giá trị tính toán từ trong thủ tục. Chúng được chỉ ra một cách rõ ràng bởi việc sử dụng sự kết hợp theo tên và kết hợp theo vị trí . Ví dụ: ARITH_UNIT (D1, D2, ADD, SUM, COMP ); -- Sự kết hợp theo vị trí. ARITH_UNIT ( Z => SUM, B=> D2, A=>D1, OP=>ADD, ZCOMP => COMP); -- Sự kết hợp theo tên. Một phát biểu gọi thủ tục tuần tự được thực thi tuần tự cùng với các phát biểu tuần tự chung quanh nó. Một phát biểu gọi thủ tục đồng thời được thực thi bất cứ lúc nào khi có một sự kiện xảy ra trên một trong các tham số, mà các tham số này là một tín hiệu ở chế độ in hoặc inout. Một lời gọi thủ tục đồng thời có nghĩa tương đương với một process có chứa một lời gọi thủ tục tuần tự và một phát biểu wait. Phát biểu wait này sẽ làm cho quá trình chờ cho đến khi có một sự kiện xuất hiện trên các tham số tín hiệu của mode in hoặc inout. Sau đây là một ví dụ của lời gọi thủ tục đồng thời và phát biểu process tương đương với nó: architecture DUMMY_ARCH of DUMMY is -- Tiếp đến là thân của thủ tục procedure INT_2_VEC ( signal D : out BIT_VECTOR ; START_BIT, STOP_BIT : in NATUAL ; signal VALUE : in INTEGER ) is begin -- Mô tả hoạt động hành vi của thủ tục end INT_2_VEC; begin -- Đây là ví dụ của một lời gọi thủ tục đồng thời. INT_2_VEC (D_ARRAY, START, STOP, SIGNAL_VALUE); end DUMMY_ARCH; Phát biểu process tương đương với lời gọi một thủ tục đồng thời như sau: process begin INT_2_VEC (D_ARRAY,START,STOP,SIGNAL_VALUE); -- Phần thể hiện của các lời gọi thủ tục tuần tự wait on SIGNAL_VALUE; -- Chờ sự kiện trên SIGNAL_VALUE và xem chúng như một tín hiệu vào. end process; Một procedure có thể sử dụng hoặc là một phát biểu đồng thời hoặc là phát biểu tuần tự. Các lời gọi đồng thời thường xuyên được dùng để mô tả chính là các process. Ví dụ của thủ tục dùng có khai báo postpone ( Trì hoãn ). postponend procedure INT_2_VEC ( signal D:out BIT_VECTOR ; START_BIT,STOP_BIT : in NATUAL; signal VALUE :in INTEGER) is begin -- Phần khai báo hoạt động của thủ tục end INT_2_VEC; Ngữ nghĩa của một lời gọi thủ tục đồng thời dùng postponed là tương đương với nhữ nghĩa của phát biểu process tương ứng với nó và được gọi là phát biểu process bị trì hoãn. Một thân process có thể có phát biểu wait, trong khi một function thì không được phép có. Các function được sử dụng để tính toán các giá trị một cách tức thì. Vì vậy một function không cần có phát biểu wait trong đó. Một function không thể gọi một procedure có phát biểu wait trong thủ tục đó. Một process mà có chứa lời gọi một thủ tục mà trong thủ tục này có chứa phát biểu wait, thì process này không được khai báo sensitivity list. Hơn nữa từ thực tế chúng ta thấy một process không thể nhận biết các tín hiệu thuộc sensitivity list vì nếu có process này sẽ rơi vào trang thái chờ ngay lập tức. Với một thủ tục có chứa phát biểu wait thì bất cứ biến hay hằng nào được khai báo trong thủ tục đó sẽ giữ nguyên giá trị của chúng trong suốt thời gian thực hiện phát biểu wait và tồn tại chỉ khi thủ tục được kết thúc. 3.8. Các đóng gói ( Packages ). Bạn có thể đóng gói để cất các chương trình con, các kiểu dữ liệu, các hằng ...thường dùng để sử dụng chúng trong các thiết kế khác. Một package bao gồm hai phần chính: Phần khai báo và phần thân package, phần khai báo chỉ ra giao tiếp cho package . Cú pháp của khai báo package như sau: package package _name is {package _declarative_item} end [package _name]; Phần package _declarative_item có thể là bất kỳ kiểu nào sau đây: - Khai báo kiểu. - Khai báo các kiểu con. - Khai báo tín hiệu. - Khai báo các hằng. - Khai báo bí danh ALIAS. - Khai báo các thành phần. - Khai báo các chương trình con. - Các mệnh đề USE. Chú ý ! khai báo tín hiệu trong package có một số vấn đề cần lưu ý trong khi tổng hợp, bởi vì một tín hiệu không thể được chia sẻ bởi hai Entity. Vì vậy nếu muốn dùng chung khai báo tín hiệu bạn phải khai báo tín hiệu này là tín hiệu toàn cục. Phần thân của package chỉ ra hoạt động thực tế của một package. Phần thân của package phải luôn có tên trùng với phần khai báo. Cú pháp của khai báo này như sau: package body package _name is {package _body_declarative-item} end [package _name] ; Phần package _body_declarative-item có thể bao gồm: - Khai báo kiểu. - Khai báo các kiểu con. - Khai báo các hằng - Mệnh đề use. - Thân các chương trình con. Ví dụ: library IEEE; use IEEE.NUMERIC_BIT.all; package PKG is subtype MONTH_TYPE is integer range 0 to 12; subtype DAY_TYPE is integer range 0 to 31; subtype BCD4_TYPE is unsigned ( 3 downto 0); subtype BCD5_TYPE is unsigned ( 4 downto 0) ; constant BCD5_1: BCD5_TYPE : = b"0_0001" ; constant BCD5_7: BCD5_TYPE : = b"0_0111" ; function BCD_INC (L : in BCD4_TYPE) return BCD5_TYPE; end PKG; package body PKG is function BCD_INC (L :in BCD4_TYPE) return BCD5_TYPE is variable V,V1, V2 : BCD5_TYPE; begin V1 : = L + BCD5_1; V2 : = L + BCD5_7; case V2(4) is when ' 0 ' => V : = V1; when ' 1 ' => V : = V2; end case; return (V); end BCD_INC; end PKG; 3.9. Mô hình cấu trúc . Thông thường một hệ thống số được mô tả theo tập hợp có thứ bậc của các thành phần . Mỗi thành phần bao gồm một tập các cổng để có thể giao tiếp được với các thành phần khác. Khi mô tả một thiết kế trong VHDL và một thiết kế có thứ bậc chính là một thiết kế đưa ra các khai báo của các thành phần và các phát biểu thể hiện thành phần đó. Một đơn vị cơ sở để diễn tả hành vi hoạt động chính là các phát biểu process, còn đơn vị cơ sở để diễn tả theo kiểu cấu trúc chính là các phát biểu thể hiện của các đơn vị thành phần. Cả hai loại này đều có thể có mặt trong một thân của một kiến trúc ( architecture ). 3.9.1. Các khai báo thành phần . Một thân kiến trúc có thể sử dụng các Entity khác (không trong cùng khai báo của architecture ), các Entity này được mô tả tách biệt và được đặt trong thư viện thiết kế. Để sử dụng chúng, người ta dùng các khai báo thành phần và các phát biểu thể hiện của chúng .Trong mô tả thiết kế, mỗi phát biểu khai báo thành phần phải tương ứng với một Entity . Các phát biểu khai báo thành phần phải giống với các phát biểu được chỉ ra trong Entity (các phát biểu giao tiếp vào ra của thành phần đó ). Cú pháp khai báo của chúng như sau: component component _name [ port ( local_port_declaration ) ] end component ; Trong đó component _name mô tả tên của Entity và port_declaration là khai báo các cổng của component và phải trùng với phần khai báo đã chỉ ra cảu component nằm trong phần khai báo của Entity. 3.9.2. Các thể hiện của component. Một component được định nghĩa trong một architecture có thể được thể hiện thông qua việc sử dụng các phát biểu thể hiện của chúng. Khi thể hiện chỉ được phép thể hiện phần giao tiếp của component ( Bao gồm tên, kiểu , hướng của các cổng vào ra của chúng ), các tín hiệu bên trong chúng không được thể hiện. Cú pháp thể hiện component như sau: instantiation_label : component _name port map ( [ local_port_name =>] expression { [local_port_name =>] expression} ); Một phát biểu thể hiện component cần phải khai báo phần nhãn của thể hiện trước instantiation_label. Hình vẽ dưới đây mô tả phần giao diện và phần thực thi bên trong của một bộ cộng full_Adder. FULL_Adder Sum Cout A B Cin Phần giao diện component của bộ cộng Full_adder. SUM Cout Cin N3 N1 N2 A B Phần thực thi bên trong của component Full_Adder. Như trên hình vẽ chúng ta thấy phần thực thi có ba loại cổng khác nhau và chúng được mang tên như sau: OR2_gate, AND2_gate, XOR_gate, chúng được dùng để xây dựng nên bộ cộng. Để mô tả và thể hiện chúng trong thiết kế, ta có thể viết chương trình để thực thi từng thành phần của chúng như sau: library IEEE; use IEEE.STD_LOGIC_1164.all; Entity AND2_gate is port ( I0, I1 : in STD_LOGIC ; O : out STD_LOGIC ); End AND2_gate; Architecture BHV of AND2_gate is Begin O <= I0 and I1; End BHV; library IEEE; use IEEE.STD_LOGIC_1164.all; Entity XOR_gate is port ( I0, I1 : in STD_LOGIC ; O : out STD_LOGIC ); End XOR_gate; Architecture BHV of XOR_gate is Begin O <= I0 xor I1; End BHV; library IEEE; use IEEE.STD_LOGIC_1164.all; Entity OR2_gate is port ( I0, I1 : in STD_LOGIC ; O : out STD_LOGIC ); End OR2_gate; Architecture BHV of OR2_gate is Begin O <= I0 xor I1; End BHV; Để thể hiện các component này trong một thiết kế, ta khai báo chúng như sau: library IEEE; use IEEE.STD_LOGIC_1164.all; Entity FULL_ADDER is port (A, B, Cin : in STD_LOGIC; Sum, Cout : out STD_LOGIC); End FULL_ADDER; Architecture IMP of FULL_ADDER is component XOR_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component ; component AND2_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component; component OR2_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component; signal N1, N2, N3: STD_LOGIC; begin U1 : XOR_gate port map (I0 => A, I1=> B, O=>N1); U2 :AND2_gate port map ( A, B, N2); U3 :AND2_gate port map ( Cin, N1, N3); U4 :XOR_gate port map ( Cin, N1, Sum); U5 :OR2_gate port map ( N3, N2, Cout); end IMP; 3.9.3. Các phát biểu Generate. Phát biểu generate là một phát biểu đồng thời và nó được định nghĩa trong phần architecture. Nó được dùng để mô tả các cấu trúc giống nhau, hay tái tạo lại các cấu trúc khác giống như bản gốc. Cú pháp của chúng như sau: instantiation _label : generation_scheme generate {concurrent_statement} end generate [instantiation _label]; Có hai loại lược đồ generation : Lược đồ for và lược đồ if. Lược đồ for được dùng để diễn tả cấu trúc thông thường, nó được dùng để khai báo một tham số generate và một dải rời rạc của lược đồ for ( chỉ ra tham số vòng lặp và dải rời rạc trong các phát biểu lặp tuần tự ). Các giá trị tham số của generate có thể được đọc nhưng không được gán hay chuyển ra ngoài phát biểu generate. a. Sử dụng lược đồ for: Ví dụ : Giả sử ta có bộ cộng 4 bit mà trong đó bao gồm bốn bộ công Full_adder như đã được mô tả ở trên. Xem hình dưới đây: X (3) Y (3) X (2) Y (2) X (1) Y (1) X (0) Y (0) Cout ' 0 ' Z (3) Z (2) Z (1) Z (0) FA (3) FA (2) FA (1) FA (0) Để mô tả bộ cộng 4 bit này và sử dụng phát biểu generate, sử dụng mô tả bộ cộng Full_Adder như trên ta đã mô tả. Ta có thể viết chúng như sau: architecture IMP of FULL_ADDER4 is signal X, Y, Z : STD_LOGIC_VECTOR ( 3 downto 0 ) ; signal Cout : STD_LOGIC ; signal TMP : STD_LOGIC_VECTOR ( 4 downto 0 ) ; component FULL_ADDER port ( A, B, Cin : in STD_LOGIC ; Sum, Cout : out STD_LOGIC ); end component ; begin TMP (0) <= ' 0 '; G : for I in 0 to 3 generate FA: FULL_ADDER port map ( X (I), Y(I), TMP (I), Z (I),TMP ( I+1 )); end generate ; Cout <= TMP (4); end IMP; b. Sử dụng lược đồ if. X (3) Y (3) X (2) Y (2) X (1) Y (1) X (0) Y (0) Cout Z (3) Z (2) Z (1) Z (0) FA (3) FA (2) FA (1) HA (0) Sơ đồ bộ cộng bốn bit sử dụng một bộ cộng Half_ADDER và ba bộ cộng FULL_ADDER Một số cấu trúc có dạng không theo qui luật chuẩn nào, với trường hợp này ta có thể sử dụng lược đồ if. Giả sử ta mô tả bộ cộng bốn bit như trên hình trên và sử dụng lựơc đồ IF generate để mô tả bộ cộng này. Chương trình được viết như sau: architecture IMP of FULL_ADDER4 is signal X, Y, Z : STD_LOGIC_VECTOR ( 3 downto 0 ) ; signal Cout : STD_LOGIC ; signal TMP : STD_LOGIC_VECTOR ( 4 downto 1) ; component FULL_ADDER port ( A, B, Cin : in STD_LOGIC ; Sum, Cout : out STD_LOGIC ); end component ; component HALF_ADDER port ( A, B : in STD_LOGIC ; Sum, Cout : out STD_LOGIC ); end component ; begin G0 : for I in 0 to 3 generate G1: if I = 0 generate HA: HALF_ADDER port map ( X (I), Y(I), Z (I), TMP ( I+1 )); end generate ; G2: if I >= 1 and I <= 3 generate FA: FULL_ADDER port map ( X (I), Y(I), TMP (I), Z (I),TMP ( I+1 )); end generate ; end generate ; Cout <= TMP ( 4 ); end IMP; 3.9.4. Các thông số của việc định cấu hình. Trong một Entity có thể có một vài cấu trúc, vì vậy các chi tiết cuả việc định cấu hình cho phép người thiết kế chọn các Entity và kiến trúc của nó. Cú pháp khai báo của chúng như sau: for instantiation _list : component _name use Entity library_name. Entity _name [( architecture _name)] ; Nếu chỉ có một kiến trúc architecture thì tên architecture có thể bị bỏ qua. Xem thêm một ví dụ dưới đây: library IEEE; use IEEE.STD_LOGIC_1164.all; Entity FULL_ADDER is port (A, B, Cin : in STD_LOGIC; Sum, Cout : out STD_LOGIC); End FULL_ADDER; Architecture IMP of FULL_ADDER is component XOR_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component ; component AND2_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component; component OR2_gate port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC ); end component; signal N1, N2, N3: STD_LOGIC; for U1 : XOR_gate use entity work.XOR_gate (BHV); for others : XOR_gate use entity work.XOR_gate (BHV); for all : AND2_gate use entity work.AND2_gate (BHV); for U5 : OR2_gate use entity work.OR2_gate (BHV); begin U1 : XOR_gate port map (I0 => A, I1=> B, O=>N1); U2 :AND2_gate port map ( A, B, N2); U3 :AND2_gate port map ( Cin, N1, N3); U4 :XOR_gate port map ( Cin, N1, Sum); U5 :OR2_gate port map ( N3, N2, Cout); end IMP; 3.10. Mô hình mức RT (Register Tranfer) và các mạch logic tổ hợp. register Combinational Logic DOUT clock DIN Một thiết kế mức chuyển đổi thanh ghi bao gồm một tập các thanh ghi được kết nối với mạch logic tổ hợp như được chỉ ra trên hình vẽ. Một process không có chứa các phát biểu if trên các sườn chuyển đổi tín hiệu hoặc các phát biểu wait trên các sự kiện của tín hiệu thì được gọi là các process tổ hợp. Tất cả các phát biểu tuần tự ngoại trừ phát biểu wait , phát biểu lặp, phát biểu if trên sườn chuyển đổi tín hiệu có thể được sử dụng để mô tả các mạch logic tổ hợp . Các mạch logc tổ hợp không có bộ nhớ để nhớ các giá trị. Vì vậy một biến hoặc một tín hiệu cần phải được gán một giá trị trước khi được tham chiếu. Đây là một ví dụ mô tả mạch logic tổ hợp : process (A, B, Cin) begin Cout <= ( A and B ) or (( A or B) and Cin ); end process ; Chú ý ! Vì không có các phát biểu if, wait, loop nên các tín hiệu vào phải thuộc danh sách sensitivity list . 3.11. Các thiết bị logic cơ bản. 3.11.1. Các bộ chốt. Các flip - flop và các bộ chốt là hai thiết bị nhớ một bit thường hay được sủ dụng nhất trong các mạch số. Một Flip - Flop chính là một thiết bị nhớ được khởi tạo bởi kích thích của sườn tín hiệu, còn bộ chốt là một thiết bị nhớ cảm nhận chuyển mức của tín hiệu. Nói chung các bộ chốt chúng được tổng hợp từ các biểu thức điều kiện không hoàn toàn rõ ràng trong việc mô tả mạch logic tổ hợp. Tất cả các tín hiệu hoặc các biến mà không được điều khiển dưới tất cả các điều kiện đều trở thành phần tử chốt. Các phát biểu if and case được chỉ ra không hoàn toàn rõ ràng đều tạo ra các bộ chốt. Ví dụ dưới đây phát biểu IF không gán một giá trị cho tín hiệu Data_out khi S không bằng ' 1', vì vậy khi tổng hợp bộ tổng hợp sẽ tạo ra một bộ chốt. Signal S, Data_in, Data_out : bit; process (S, Data_in) Begin if ( S = '1' ) then Data_out <= Data_in; end if; end process ; S Q Q SET CLR D Data_In Data_out Để tránh bị chốt nhầm ta phải gán tất cả các giá trị tới tất cả các tín hiệu dưới tất cả các điều kiện, thêm vào phát biểu else của ví dụ trước thì bộ tổng hợp sẽ tổng hợp như một cổng AND. xem ví dụ dưới đây: Signal S, Data_in, Data_out : bit; process (S, Data_in) Begin if ( S = '1' ) then Data_out <= Data_in; else Data_out <= ' 0 '; end if; end process ; Data_In S Data_out Chúng ta có thể chỉ ra một bộ chốt với đường reset không đồng bộ hoặc các đường preset không đồng bộ như sau: S Q Q SET CLR D Data_In Data_out en RST Signal S, RST, Data_in, Data_out : bit; process (S, RST, Data_in) Begin if ( RST = '1' ) then Data_out <= ' 0 '; elsif ( S = ' 1 ' ) then Data_out <= Data_in; end if; end process ; Thay vì đường Data_out được gán bằng ' 0 ', chúng ta có thể gán '1' cho đường Preset không đồng bộ. 3.11.2. Các FLIP - FLOP. Một process với các phát biểu if trên sườn chuyển tín hiệu hoặc các phát biểu wait trên sự kiện của tín hiệu được gọi là một quá trình thực hiện theo nhịp đồng hồ. Một Flip - Flop sẽ đựoc tạo ra nếu có được một kích thích bởi một sườn tín hiệu, hơn nữa nếu phép gán tín hiệu được thực hiện trên việc kích thích chuyển mức của một tín hiệu khác. Ví dụ : Signal CLK, Data_in, Data_out : bit; process (CLK) Begin if ( CLK'event and CLK = '1' ) then Data_out <= Data_in; end if; end process ; CLK Q Q SET CLR D Data_In Data_out 3.11.3. Các đường tín hiệu SET và RESET đồng bộ. Việc thiết lập các đầu vào (SET) và reset các đầu ra đồng bộ của Flip - Flop cùng với hoạt động của hệ thống đồng hồ, ngoài các khoảng thời gian khác các tín hiệu này không được xem xét, điều này được thực hiện bởi phần tử nhớ. Signal CLK, S_RST, Data_in, Data_out : bit; process (CLK) Begin if ( CLK'event and CLK = '1' ) then if (S_RST = '1') then Data_out <= ' 0 '; else Data_out <= Data_in; end if; end if; end process ; CLK Q Q SET CLR D Data_In Data_out ' 0 ' S_RST MUX 3.11.4. Các đường tín hiệu SET và RESET không đồng bộ. CLK Q Q SET CLR D Data_In Data_out A_RST Signal CLK, A_RST, Data_in, Data_out : bit; process (CLK, A_RST) Begin if ( A_RST = '0' ) then Data_out <= ' 0 '; elsif ( CLK'event and CLK = ' 1 ' ) then Data_out <= Data_in; end if; end process ; Các đường SET và RESET của Flip - Flop hoạt động độc lập với đường Clock. 3.11.5. Các mạch RTL tổ hợp và đồng bộ. Chúng ta có thể chia các phát biểu của một process RTL thành vài mạch tổ hợp và vài mạch đồng bộ. Phần mạch đồng bộ dùng để mô tả các mạch con mà các hoạt động hành vi của chúng chỉ được được định lượng khi có chuyển mức của tín hiệu. Phần mạch tổ hợp dùng để mô tả các mạch con mà hoạt động hành vi của chúng sẽ được định lượng bất cứ khi nào có sự thay đổi của tín hiệu thuộc sensitivity list . Tất cả các tín hiệu được tham chiếu trong phần mạch tổ hợp cần phải thuộc trong danh sách sensitivity list . Xem ví dụ sau: PB CLK Q1 Q2 PB.Pulse FF FF Entity PULSER is port ( CLK, PB : in bit; PB_PULSER : out bit ); end PULSER; architecture BHV of PULSER is signal Q1, Q2 : bit; begin process ( CLK, Q1, Q2 ) begin if ( CLK'event and CLK = ' 1' ) then Q1 <= PB; Q2 <= Q1; end if; PB_PULSE <= ( not Q1 ) nor Q2; end process ; end BHV; 3.11.6. Các thanh ghi. Có rất nhiều kiểu thanh ghi mà chúng được sử dụng trong một mạch. Ví dụ sau đây sẽ chỉ ra một thanh ghi bốn bit mà chúng được đặt trước không đồng bộ ở vị trí " 1100 ". S Q D S Q D Q D R Q D R Dout (3) Dout (2) Dout (1) Dout (0) Din (3) Din (2) Din (1) Din (0) CLK ASYNC signal CLK, ASYNC : Bit; signal Din, Dout : Bit_vector ( 3 downto 0 ); process ( CLK, ASYNC ) begin if (ASYNC = '1' ) then Dout <= " 1100 "; elsif ( CLK'event and CLK = '1' ) then Dout <= Din; end if; end process ; 3.11.7. Thanh ghi dịch. Một thanh ghi có khả năng dịch các bit thông tin hoặc sang phải hoặc sang trái được gọi là một thanh ghi dịch. Cấu hình logic của thanh ghi bao gồm một loạt các Flip - Flop được nối tầng với nhau, đầu ra của Flip - Flop này được nối vào đầu vào của Flip - Flop kia. Tất cả các Flip - Flop đều nhận xung đồng hồ chung nên nó có thể làm cho dữ liệu dịch từ trạng thái này sang trạng thái tiếp theo. Xét ví dụ về thanh ghi dịch 4 bít sau: signal CLK, Din, Dout : Bit ; process (CLK) variable REG : bit_vector ( 3 down to 0 ); begin if ( CLK'event and CLK = '1' ) then REG : = Din & REG ( 3 downto 1); end if; Dout <= REG (0); end process ; Cấu hình của chúng như sau: FF FF FF FF Din CLK D D D DQ Q Q Q Dout 3.11.8. Các bộ đếm không đồng bộ. Bộ đếm không đồng bộ là bộ đếm mà trạng thái của nó thay đổi không bị điều khiển bởi các xung đồng bộ đồng hồ. Cách mô tả bộ đếm này như sau: FF T FF T FF T FF TQ Q Q Q RESET CLK Count (0) Count (1) Count (2) Count (3) 1 1 1 1 signal CLK, RESET : Bit; signal COUNT : Bit_vector ( 3 downto 0 ); process ( CLK, COUNT, RESET ) begin if RESET = '1' then COUNT <= "0000"; else if (CLK' event and CLK = '1' ) then COUNT (0) <= not COUNT (0); end if; if (COUNT(0)' event and COUNT(0) = '1' ) then COUNT (1) <= not COUNT (1); end if; if (COUNT(1)' event and COUNT(1) = '1' ) then COUNT (2) <= not COUNT (2); end if; if (COUNT(2)' event and COUNT(2) = '1' ) then COUNT (3) <= not COUNT (3); end if; end if; end process ; 3.11.9. Các bộ đếm đồng bộ. Nếu tất cả các Flip - Flop của bộ đếm được điều khiển bởi tín hiệu clock chung thì chúng được gọi là bộ đếm đồng bộ. Cách viết chúng như sau: signal CLK, RESET, load, Count, Updown : Bit; signal Datain : integer range 0 to 15; signal Reg : integer range 0 to 15: = 0; process ( CLK, RESET ) begin if RESET = '1' then Reg <= 0; elsif ( CLK'event and CLK = '1' ) then if ( Load = ' 1' ) then Reg <= Datain; else if (Cout = '1' ) then if Updown = '1' then Reg <= ( Reg +1) mod 16; else Reg <= ( Reg -1 ) mod 16; end if; end if; end if; end if; end process ; 3.11.20. Các bộ đệm ba trạng thái. Bên cạnh các số 0 và 1, còn một tín hiệu thứ ba trong hệ thống số : đó là trạng thái trở kháng cao ( Z ). Trong các ki

Các file đính kèm theo tài liệu này:

  • pdfso_tay_lap_trinh_vhdl_0176.pdf
Tài liệu liên quan