Sunday, July 27, 2014

โปรแกรมภาษา VHDL สำหรับโมดูลภาครับสัญญาณเอนโคเดอร์

บทความเดิม: Quadrature Encoder Receiver Module: An Implementation on FPGA

(เป็นภาษาอังกฤษ สำหรับภาษาไทยได้กล่าวไว้ในบทที่ 10 ของหนังสือ วิศวกรรมไฟฟ้าและคอมพิวเตอร์ประยุกต์ )

ในบทความข้างต้น เราได้กล่าวถึงการออกแบบโมดูลภาครับสัญญาณจากเอนโคเดอร์ของมอเตอร์โดยใช้ภาษา Verilog ในบทความนี้จะเป็นส่วนเสริมสำหรับผู้ที่คุ้นเคยกับภาษา VHDL โดยเนื้อหาและขั้นตอนการออกแบบจะเป็นเช่นเดิม ดังนั้นจะไม่กล่าวถึงอีก เพียงแต่จะแสดงโค้ด VHDL และผลการจำลองสำหรับโมดูลแบบ A และ B เท่านั้น

โมดูลแบบ A

สำหรับการออกแบบโมดูลแบบ A ที่กล่าวถึงในบทความเดิม ภาครับจะกำเนิดพัลส์ที่ขาเอาต์พุต U (นับขึ้น) หรือ D (นับลง) ขึ้นอยู่กับว่าอินพุต A นำหน้า B หรือ A ตามหลัง B (*) เราได้แสดงการออกแบบโดยอาศัย STG (State Transition Graph) ทำให้ได้ผลตามสมการ (1) – (4) ที่นำมาอิมพลิเมนต์ โดยโค้ด VHDL จะแสดงตามโปรแกรมที่ 1 และผลการจำลองดังในรูปที่ 1 (การสังเคราะห์วงจรและการจำลองกระทำบนซอฟต์แวร์ ISE Webpack 13.4 ที่ดาวน์โหลดได้ฟรีจาก เว็บของบริษัท Xilinx

(*) มีความสับสนในบทความเดิมและในหนังสือ คือ ข้อมูลในคาร์นอฟ แมพสำหรับเอาต์พุต U และ D สลับกัน ทำให้สมการ (3) และ (4) สลับกันด้วย ซึ่งจะสังเกตได้จากผลการจำลอง คือเมื่อ A นำหน้า B พัลซ์เอาต์พุตจะออกที่ขา D แทน อย่างไรก็ตามทิศทางการหมุนขึ้นอยู่กับเอนโคเดอร์ที่ใช้ด้วย ถ้าหากทิศทางไม่ถูกต้องผู้ใช้สามารถสลับสมการ (3) และ (4) เพื่อแก้ไข สำหรับในโค้ด VHDL ด้านล่างเราจะยึดว่า สัญญาณออกที่ขา U เมื่อ A นำหน้า B

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity x4enc1 is
    Port ( A,B,Clk : in  STD_LOGIC;
           U,D : out  STD_LOGIC);
end x4enc1;
architecture Behavioral of x4enc1 is
 signal Q0, Q1 : STD_LOGIC;
begin
process (Clk)
begin
 if (Clk'event and Clk='1') then
  Q0 <= A xor B;
  Q1 <= B;
 end if;
end process;
U <= (not A and not B and Q1) or (not A and Q1 and not Q0) 
or (A and not Q1 and not Q0) or (A and B and not Q1);
D <= (not A and B and not Q1) or (not A and not Q1 and Q0) 
or (A and Q1 and Q0) or (A and not B and Q1);
end Behavioral;
โปรแกรม 1: โค้ด VHDL สำหรับภาครับสัญญาณเอนโคเดอร์ (แบบ A ใช้วิธี STG)

ดาวน์โหลดและเพิ่มซอร์สนี้ในโปรเจ็ค Xilinx ISE

  • x4enc1.vhd -- โค้ดที่แสดงในโปรแกรม 1
  • x4enc1_tb.vhd -- VHDL test bench สำหรับจำลองการทำงาน

รูปที่ 1: ผลการจำลองสำหรับภาครับสัญญาณเอนโคเดอร์ (แบบ A ใช้วิธี STG

การออกแบบโดยใช้ STG ในการสร้างสมการตรรกอาจกระทำได้สำหรับปัญหาง่ายๆ แต่สำหรับวงจรที่ซับซ้อนจะเกิดข้อผิดพลาดได้ง่าย และเราไม่ได้ใช้ความสามารถของซอฟต์แวร์ให้เต็มที่ ดังนั้นวิธีการที่ดีกว่าคือเขียนแผนภาพ ASM (Algorithmic State Machine) ดังในรูปที่ 2 และสร้างโปรแกรม VHDL จากแผนภาพโดยตรงดังแสดงในโปรแกรม 2 ผลการจำลองในรูปที่ 3 แสดงให้เห็นว่าโมดูลทำงานให้ผลเช่นเดียวกับวิธีการออกแบบโดย STG

รูปที่ 2: แผนภาพ ASM สำหรับภาครับสัญญาณเอนโคเดอร์ (แบบ A)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity x4enc2 is
    Port ( AB : in  STD_LOGIC_VECTOR (1 downto 0);
           Clk : in  STD_LOGIC;
           UD : out  STD_LOGIC_VECTOR (1 downto 0));
end x4enc2;

architecture Behavioral of x4enc2 is
 signal State: STD_LOGIC_VECTOR (1 downto 0) := "00";
 -- State 0 = "00", State 1 = "01",
-- State 2 = "10", State 3 = "11"
begin
process (CLk)
begin
 if (Clk'event and Clk='1') then
  case State is
   when "00" => -- State 0
    case AB is
     when "00" => UD <= "00";-- stays at State 0
     when "01" => UD <= "01"; State <= "11"; -- to State 3
     when "10" => UD <= "10"; State <= "01"; -- to State 1
     when others => UD <= "00";
    end case;
   when "01" =>  -- State 1
    case AB is
     when "00" => UD <= "01"; State <= "00"; -- to State 0
     when "10" => UD <= "00"; -- stays at State 1
     when "11" => UD <= "10"; State <= "10"; -- to State 2
     when others => UD <= "00";
    end case;
   when "10" => -- State 2
     case AB is
     when "01" => UD <= "10"; State <= "11"; -- to State 3
     when "10" => UD <= "01"; State <= "01"; -- to State 1
     when "11" => UD <= "00";  -- stays at State 2
     when others => UD <= "00";
    end case;
   when "11" => -- State 3
    case AB is
     when "00" => UD <= "10"; State <= "00"; -- to State 0
     when "01" => UD <= "00"; -- stays at State 3
     when "11" => UD <= "01"; State <= "10"; -- to State 2
     when others => UD <= "00";
    end case;
   when others => null; 
  end case;
 end if;
end process;

end Behavioral;

โปรแกรม 2: โค้ด VHDL สำหรับภาครับสัญญาณเอนโคเดอร์ (แบบ A ใช้วิธี ASM)

ดาวน์โหลดและเพิ่มซอร์สนี้ในโปรเจ็ค Xilinx ISE

  • x4enc2.vhd -- โค้ดที่แสดงในโปรแกรม 2
  • x4enc2_tb.vhd -- VHDL test bench สำหรับจำลองการทำงาน

รูปที่ 3: ผลการจำลองสำหรับโมดูลรับสัญญาณเอนโคเดอร์ (แบบ A ใช้วิธี ASM)

โมดูลแบบ B

ในบทความเดิม โมดูลแบบ B ใช้สำหรับกรณีวงจรนับเป็นแบบรับสัญญาณพัลส์และลอจิกกำหนดทิศทาง ดังนั้นโมดูลจะต้องกำเนิดเอาต์พุต P (พัลส์) และ DIR (ทิศทาง) โดยคำอธิบายเพิ่มเติมสามารถอ่านได้จากบทความ ในที่นี้เราจะแสดงโค้ด VHDL ในโปรแกรม 3 และผลการจำลองในรูปที่ 4 ที่ให้ผลเหมือนกับที่ได้จากโค้ด Verilog ในบทความเดิม

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity x4enc3 is
    Port ( A,B, Clk : in  STD_LOGIC;
           P,Dir : out  STD_LOGIC);
end x4enc3;

architecture Behavioral of x4enc3 is
signal Ar, Br : STD_LOGIC_VECTOR (1 downto 0) := "00";
begin
process (Clk,A,B)
begin
 if (Clk'event and Clk='1') then
  Ar <= (Ar(0)&A);
  Br <= (Br(0)&B);
  if (Ar = "01") then -- rising edge of A
   P <= '1';
   if (B = '0') then Dir <= '1'; -- A leads B
   else Dir <= '0';     -- B leads A
   end if;
  elsif (Ar = "10") then -- falling edge of A
   P <= '1';
   if (B = '1') then Dir <= '1'; -- A leads B
   else Dir <= '0';     -- B leads A
   end if;
  elsif (Br = "01") then -- positive edge of B
   P <= '1';
   if (A = '1') then Dir <= '1'; -- A leads B
   else Dir <= '0';     -- B leads A
   end if;
  elsif (Br = "10") then -- positive edge of B
   P <= '1';
   if (A = '0') then Dir <= '1'; -- A leads B
   else Dir <= '0';     -- B leads A
   end if;
  else P <= '0';
  end if;
 end if;
 
end process;
end Behavioral;

โปรแกรม 3: โค้ด VHDL สำหรับโมดูลรับสัญญาณเอนโคเดอร์ (แบบ B)

ดาวน์โหลดและเพิ่มซอร์สนี้ในโปรเจ็ค Xilinx ISE

  • x4enc3.vhd -- โค้ดที่แสดงในโปรแกรม 3
  • x4enc3_tb.vhd -- VHDL test bench สำหรับจำลองการทำงาน

รูปที่ 4: ผลการจำลองสำหรับโมดูลรับสัญญาณเอนโคเดอร์ (แบบ B)

No comments:

Post a Comment