Chương 9: Bài tập tham khảo
9.5. Bộ điều khiển máy bán hàng
Trong ví dụ này, chúng ta sẽ thiết kế bộ điều khiển máy bán hàng, máy bán hàng sẽ bán các thanh kẹo với giá 25 xu. Chúng ta sẽ thiết kế theo mô hình máy FSM. Đầu ra và đầu vào của bộ điều khiển được thể hiện trong hình 9.11.
Tín hiệu vào là nickel_in, dime_in, và quarter_in thông báo rằng một đồng tiền tương ứng được gửi vào tài khoản. Ngoài ra còn có 2 đầu vào điều khiển: đầu vào reset (rst) và đầu vào clock (clk). Bộ điều khiển trả lời bằng 3 tín hiệu đầu ra: candy_out (để phân phát thanh kẹo), nickel_out và dime_out(cập nhật lại thay đổi).
Trên hình 9.11 cũng chỉ ra đồ hình trạng thái của máy FSM. Các số bên trong các vòng tròn biểu diễn tổng tài khoản của khách hàng (chỉ có các nickel, dime và quarter là được chấp nhận).
Hình 9.11. Đồ hình trạng thái của bộ điều khiển máy bán hàng Trạng thái 0 là trạng thái là trạng thái không làm gì cả. 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. Tình huống tương tự sẽ được lặp lại cho tất cả các trạng thái, cho tới trạng thai 20. Nếu trạng thái 25 được xác nhận, thì thanh kẹo được phân phát và không chuyển đổi. Tuy nhiên nếu trạng thái 40 được xác nhận thì a nickel được trả lại, bởi vậy trạng thái sẽ chuyển tới trạng thái 35, đó là 1 trạng thái mà 1 dime được trả lại và 1 candy bar được phân phát. Có 3 trạng thái tạo ra chu trình kép, đó là từ 1 thanh kẹo được phân phát và máy trở lại trạng thái 0. Bài toán này sẽ được chia thành 2 phần:
+ 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:
--- LIBRARY ieee;
USE ieee.std_logic_1164.all;
--- ENTITY Bo_dieu_khien_may_bh IS
PORT ( clk, rst: IN STD_LOGIC;
nickel_in, dime_in, quarter_in: IN BOOLEAN;
candy_out, nickel_out, dime_out: OUT STD_LOGIC);
END Bo_dieu_khien_may_bh;
--- ARCHITECTURE state_machine OF Bo_dieu_khien_may_bh IS TYPE state IS (st0, st5, st10, st15, st20, st25,
st30, st35, st40, st45);
SIGNAL present_state, next_state: STATE;
BEGIN
---- Lower section of the FSM (Sec. 8.2): --- PROCESS (rst, clk)
BEGIN
IF (rst='1') THEN
present_state <= st0;
ELSIF (clk'EVENT AND clk='1') THEN present_state <= next_state;
END IF;
END PROCESS;
---- Upper section of the FSM (Sec. 8.2): --- PROCESS (present_state, nickel_in, dime_in, quarter_in) BEGIN
CASE present_state IS WHEN st0 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st5;
ELSIF (dime_in) THEN next_state <= st10;
ELSIF (quarter_in) THEN next_state <= st25;
ELSE next_state <= st0;
END IF;
WHEN st5 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st10;
ELSIF (dime_in) THEN next_state <= st15;
ELSIF (quarter_in) THEN next_state <= st30;
ELSE next_state <= st5;
END IF;
WHEN st10 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st15;
ELSIF (dime_in) THEN next_state <= st20;
ELSIF (quarter_in) THEN next_state <= st35;
ELSE next_state <= st10;
END IF;
WHEN st15 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st20;
ELSIF (dime_in) THEN next_state <= st25;
ELSIF (quarter_in) THEN next_state <= st40;
ELSE next_state <= st15;
END IF;
WHEN st20 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st25;
ELSIF (dime_in) THEN next_state <= st30;
ELSIF (quarter_in) THEN next_state <= st45;
ELSE next_state <= st20;
END IF;
WHEN st25 =>
candy_out <= '1';
nickel_out <= '0';
dime_out <= '0';
next_state <= st0;
WHEN st30 =>
candy_out <= '1';
nickel_out <= '1';
dime_out <= '0';
next_state <= st0;
WHEN st35 =>
candy_out <= '1';
nickel_out <= '0';
dime_out <= '1';
next_state <= st0;
WHEN st40 =>
candy_out <= '0';
nickel_out <= '1';
dime_out <= '0';
next_state <= st35;
WHEN st45 =>
candy_out <= '0';
nickel_out <= '0';
dime_out <= '1';
next_state <= st35;
END CASE;
END PROCESS;
END state_machine;
---
Kết quả mô phỏng:
Hình 9.12.Kết quả mô phỏng bộ điều khiển máy bán hàng