Thiết kế mạch vi bằng ngôn ngữ mô tả phần cứng VHDL

MỤC LỤC

Cấu trúc mã

Mục đích của 3 gói/thư viện được kể ở trên là như sau: gói std_logic_1164 của thư viện ieee cho biết một hệ logic đa mức; std là một thư viện tài nguyên (kiểu dữ kiệu, i/o text.) cho môi trường thiết kế VHDL và thư viện work được sủ dụng khi chúng ta lưu thiết kế ( file .vhd, các file được tạop bởi chương trình dịch và chương trình mô phỏng…). Như với ví dụ mô tả mô hình cấu trúc một flip-flop RS gồm hai cổng NAND có thể mô tả cổng NAND được định nghĩa tương tự như ví dụ với cổng NOT, sau đó mô tả sơ đồ móc nối các phần tử NAND tạo thành trigơ RS.

Kiểu dữ liệu

“weak”, chúng được giải quyết trong sự ưu tiên của các giá trị “forcing” trong các nút đa chiều ( Bảng 3.1). Thật vậy, nếu 2 tín hiệu std_logic bất kỳ được nối đến cùng một node, thì các mức logic đối lập được tự động giải quyết theo Bảng 3.1. Hệ thống logic giải được. Thật vậy, hệ STD_LOGIC mô tả ở trên là một tập con của STD_ULOGIC. Hệ thống thứ 2 này thêm giá trị logic ‘U’. • Physic literals: sử dụng đối với các đại lượng vật lý, như thời gian, điện áp,…Hữu ích trong mô phỏng. • Character literals: ký tự ASCII đơn hoặc một chuỗi các ký tự như thế. • SIGNED và UNSIGNED: các kiểu dữ liệu được định nghĩa trong gói std_logic_arith của thư viện ieee. Chúng có hình thức giống như STD_LOGIC_VECTOR, nhưng ngọai trừ các toán tử số học, mà tiêu biểu là kiểu dữ liệu INTEGER. Các ví dụ:. Ví dụ: Các toán tử được phép và không được phép nằm giữa các kiểu dữ liệu khác nhau:. SIGNAL a: BIT;. SIGNAL c: STD_LOGIC;. -- STD_LOGIC_VECTOR). Lý do chính cho việc sử dụng kiểu dữ liệu con để sau đó định ra một kiểu dữ liệu mới đó là, các thao tác giữa các kiểu dữ liệu khác nhau không được cho phép, chúng chỉ được cho phép trong trường hợp giữa một kiểu con và kiểu cơ sở tương ứng với nó.

Hình 3.2. M ạch được suy ra từ mã của v í dụ 3.2  Kết quả mô phỏng trên Active HDL 6.1:
Hình 3.2. M ạch được suy ra từ mã của v í dụ 3.2 Kết quả mô phỏng trên Active HDL 6.1:

Toán tử và thuộc tính

GENERIC

VARIABLE temp1 : STD_LOGIC_VECTOR (x'HIGH. END PROCESS;. END generic_decoder;. Hình sau đây mô tả kết quả hoạt động của bộ giải mã trên. Như chúng ta thấy khi ena =0 thì tất cả các bít phía đầu ra đều bằng 1. Trong ví dụ trên ta đã sử dụng các toán tử +, * , các toán tử gán và thuộc tính RANGE. Ví dụ sau đây mô phỏng một mạch phát hiện tính parity. Nó bao gồm một đầu vào n bít và một đầu ra. Đầu ra sẽ có giá trị bằng 0 khi số đầu vào có giá trị là một là một số chẵn và bằng 1 trong các trường hợp còn lại. Bộ phát hiện bít chãn lẻ Sau đây là mã nguồn mô tả mạch trên. ENTITY parity_det IS. output: OUT BIT);. Như vậy mạch sẽ gồm n-1 đầu vào dữ liệu và n đầu ra, trong đó n-1 đầu ra bên phải giống như n-1 đầu vào, đầu ra còn lại là giá trị kiểm tra parity.

Mã song song

GENERATE

Nó tương đương với khối lệnh tuần tự LOOP trong việc cho phép các đoạn lệnh được thực hiện lặp lại một số lần nào đó. Một điều cần phải chú ý là giới hạn của dãy phải được khai báo là static nếu không sẽ không hợp lệ. Trong đó đầu vào sẽ được dịch đi một bít và tạo thành đầu ra.

BLOCK

Nó chứa một điều kiện và BLOCK chỉ được thực hiện khi điều kiện đó có giá trị là TRUE. Ví dụ 2: DFF dùng Guarded BLOCK.Trong ví dụ này chúng ta sẽ xem xét hoạt động của một TrigerT hoạt động đồng bộ sườn dương.

Mã tuần tự

    Điều đó không phải là trường hợp của SIGNAL (khi được sử dụng trong PROCESS), giá trị mới của nó chỉ tổng quát được bảo toàn để có thể dùng được sau khi kết thúc quá trình chạy hiện tại của PROCESS. (other statements) END LOOP;. Bộ cộng có nhớ 8 bit không dấu. Bộ cộng có nhớ 8 bit không dấu. Kết quả mô phỏng. Mỗi phần tử của sơ đồ là một bộ cộng đầy đủ. Dùng Generic với các VECTOR. LIBRARY ieee;. ENTITY adder IS. cin: IN STD_LOGIC;. cout: OUT STD_LOGIC);. Ví dụ: lệnh IF (clk’EVENT and clk=’1’) là đúng, nhưng chỉ sử dụng IF (clk’EVENT) có thể trình biên dịch giả sử một giá trị kiểm tra mặc định (and clk=’1’) hoặc thông báo một thông điệp “clock not locally stable”.

    Nếu trình biên dịch giả thiết một giá trị mặc định, một mạch lỗi sẽ được tổng hợp, bởi vì chỉ một sườn của clk sẽ được quan tâm; nếu không có giá trị mặc định giả thiết, thì một thông điệp lỗi và không có sự biên dịch được mong muốn.

    Hình 6.6a.2. Kết quả mô phỏng
    Hình 6.6a.2. Kết quả mô phỏng

    Signal và Variable

    SIGNAL

    Khai báo của SIGNAL có thể được tạo ra ở các chỗ giống nhau như là khai báo CONSTANT. Khía cạnh quan trọng của SIGNAl, khi sử dụng bên trong một phần của mã tuần tự (PROCESS), sự cập nhật nó không tức thì. Giá trị mới của không nên được đợi để được đọc trước khi kết thúc PROCESS, FUNCTION, hoặc PROCEDURE tương ứng.

    Trình biên dịch có thể thông báo và thoát sự tổng hợp, hoặc có thể suy ra mạch sai (bằng cách chỉ xét phép gán cuối cùng).

    VARIABLE

    Tóm lại, chỉ một phép gán với SIGNAL được phép bên trong PROCESS, vì vậy phần mềm chỉ xét phép gán cuối cùng (sel <= sel +2) hoặc đơn giản là đưa ra thông báo lỗi và kết thúc việc biên dịch. Đây cũng không bao giờ là vấn đề khi sử dụng VARIABLE. DFF với q và qbar. LIBRARY ieee;. ENTITY dff IS. q: BUFFER STD_LOGIC;. qbar: OUT STD_LOGIC);. PROCESS (clk). VARIABLE temp: BIT;. DFF với q và qbar. Cách 2 có một trong các phép gán là đồng bộ, việc tổng hợp sẽ luôn suy ra chỉ một flip-flop. Sinh hai DFF. LIBRARY ieee;. ENTITY dff IS. q: BUFFER STD_LOGIC;. qbar: OUT STD_LOGIC);. Tuy nhiên, một phép gán cho một biến là tức thì, và khi các biến đang được sử dụng trong thứ tự trực tiếp (sau khi các giá trị vừa được gán cho chúng), dòng 13-15 thành 1 dòng, tương đương với c:=din.

    Phép gán tại sự chuyển tiếp của tín hiệu khác được tạo ra cho một biến (dòng 17-18), nhưng khi giá trị của nó rời PROCESS (nó được chuyển đến một port trong dòng 20), nó cũng suy ra các thanh ghi.

    Bảng 7.1. So sánh giữa SIGNAL và VARIABLE  Ví dụ 7.3b:
    Bảng 7.1. So sánh giữa SIGNAL và VARIABLE Ví dụ 7.3b:

    Máy trạng thái

    Thông thường các tín hiệu clock và các tín hiệu reset trong phần mạch dãy sẽ xuất hiện trong PROCESS (trừ khi tín hiệu reset là đồng bộ hoặc không được sử dụng, tín hiệu WAIT được sử dụng thay cho lệnh IF). Một điều quan trọng liên quan tới phương pháp FSM là : về nguyên tắc chung là bất kỳ một mạch dãy nào cũng có thể được mô hình hoá thành 1 máy trạng thái, nhưng điều này không phải luôn luôn thuận lợi. Vì có nhiều trường hợp (đặc biệt là các mạch thanh ghi như: bộ đếm,…) nếu thiết kế theo phương pháp FSM thì mã nguồn có thể trở nên dài hơn, phức tạp hơn, mắc nhiều lỗi hơn so với phương pháp thông thường.

    Ví dụ, chúng ta có thể sử dụng một tín hiệu thêm (như tín hiệu trung gian) để tính toán giá trị đầu ra (đoạn trên), nhưng chỉ chuyển các giá trị của nó thành tín hiệu đầu ra khi sự kiện clock thay đổi (phần mạch dãy).

    Hình 8.7.Kết quả mô phỏng cho ví dụ 8.3  Ví dụ 8.4. Bộ phát hiện chuỗi
    Hình 8.7.Kết quả mô phỏng cho ví dụ 8.3 Ví dụ 8.4. Bộ phát hiện chuỗi

    Thiết kế thêm các mạch

    --- ARCHITECTURE arc OF Bo_cong_carry_ripple IS SIGNAL c: STD_LOGIC_VECTOR (n DOWNTO 0);. END GENERATE;. Kết quả mô phỏng:. Kết quả mô phỏng cho bộ cộng ripple carry. + Bộ cộng carry look ahead:. Sơ đồ bộ cộng carry look ahead. Mạch được hoạt động dựa trên các khái niêm generate và propagate. Chính đặc điểm này đã làm cho bộ cộng này thực hiện với tốc độ nhanh hơn so với bộ cộng trước. Nếu chúng ta xem a, b là các vector:. Từ công thức tình trên, chúng ta viết chương trình thiết kế bộ cộng carry look ahead 4 bit như sau:. --- ENTITY Bo_cong_carry_look_ahead IS. cin: IN STD_LOGIC;. cout: OUT STD_LOGIC);. Từ đó nếu 1 đồng nickel được gửi vào tài khoản, máy sẽ chuyển trạng thái đến trạng thái 5, nếu 1 đồng dime được gửi vào tài khoản thì máy chuyển tới trạng thái 10 hoặc nếu 1 đồng quarter thì máy sẽ chuyển đến trạng thái 25. + Trong phần đầu: diện mạo cơ bản liên quan đến thiết kế bộ điều khiển máy bán hàng (như trong hình 9.11). + Trong phần 2: Các chức năng mở rộng được thêm vào. Ở đây chúng ta chỉ nghiên cứu phần một của bài toán: Nhìn vào đồ hình trạng thái của máy ở hình 9.11, chúng ta thấy có 10 trạng thái, như vậy cần có 4 bit để mã hoá các trạng thái, tức là cần sử dụng 4 flip-flop. Mã thiết kế sẽ như sau:. --- ENTITY Bo_dieu_khien_may_bh IS. nickel_in, dime_in, quarter_in: IN BOOLEAN;. candy_out, nickel_out, dime_out: OUT STD_LOGIC);.

    Khi load ở trạng thái cao thì dữ liệu được nạp vào thanh ghi dịch theo thư tự bit MSB là bít gần đầu ra nhất, và đầu ra là d(7). Mỗi khi load trả lại “0” thì bit tiếp theo được xuất hiện tại đầu ra của mỗi sườn dương của xung đồng hồ. Sau khi tất cả 8 bit được gửi đi, đầu ra trở lại mức thấp cho đến lần chuyển đổi tiếp theo. Mã thiết kế như sau:. LIBRARY ieee;. clk, load: IN STD_LOGIC;. dout: OUT STD_LOGIC);.

    Hình 9.5.2. Kết quả của bộ so sánh không dấu2  9.3.  Bộ cộng Carry Ripple và bộ cộng Carry Look Ahead
    Hình 9.5.2. Kết quả của bộ so sánh không dấu2 9.3. Bộ cộng Carry Ripple và bộ cộng Carry Look Ahead