วันศุกร์ที่ 21 พฤศจิกายน พ.ศ. 2557

การทดลองวันที่ wed 110514 โจทย์ข้อ 2


ออกแบบวงจรดิจิทัล(เลื่อนบิต)สำหรับ FPGA โดยใช้ภาษา VHDL

วัตถุประสงค์

  • ออกแบบวงจรดิจิทัลสำหรับ FPGA โดยใช้ภาษา VHDL ตามที่โจทย์กำหนดได้
  • เข้าใจการทำงานของโปรแกรม ในการสร้างวงจร เลื่อนบิต และทดสอบ simulation ก่อนลงบอร์ด FPGA
  • ฝึกการใช้งานบนบอร์ด FPGA เพื่อทดลองวงจรที่ออกแบบได้

อุปกรณ์การทดลอง

  • บอร์ด FPGA                                       1  อัน
  • โปรแกรม  Quartus II

ขั้นตอนการทดลอง

  1. ออกแบบวงจรตามโจทย์ปฏิบัติดังนี้
    - มีอินพุต CLK ความถี่ 50MHz (ได้จากวงจรความถี่บนบอร์ด FPGA)
    - มีอินพุต PB จากปุ่มกด push-button (active-low) หนึ่งชุดที่มีอยู่บนบอร์ด FPGA
    - มีขา LEDs(7:0) ซึ่งเป็นเอาต์พุตและต่อกับ LED 8 ดวงบนบอร์ด FPGA
    - เริ่มต้น LEDs(7:0) จะมีเพียงดวงเดียวที่ติดซึ่งเป็นดวงทางขวาสุด LEDs(0) และดวงที่เหลือจะไม่ติด
    - เมื่อกดปุ่มแล้วปล่อยหนึ่งครั้ง จะทำให้ตำแหน่งของ LED ที่ติด (ON) เลื่อนไปทางซ้ายหนึ่งตำแหน่งถัดไป ถ้าเลื่อนไปทางซ้ายสุดแล้ว จะกลับไปเริ่มที่ตำแหน่งขวาสุด
    - ให้ออกแบบโดยใช้ภาษา VHDL
  2. ทดลองวงจรในบอร์ด FPGA
  3. เขียนรายงานการทดลอง

ผลการทดลอง


-- File: LEDSHIFT.vhd
-- Target Board: Cyclone III, EP3C10E144C8
-- Pin Assignments
-- PIN_22 to CLK (50 MHz)
-- PIN_88 to PB input
-- q output (7:0)
-- PIN_50 to LEDS[7]
-- PIN_49 to LEDS[6]
-- PIN_46 to LEDS[5]
-- PIN_44 to LEDS[4]
-- PIN_43 to LEDS[3]
-- PIN_42 to LEDS[2]
-- PIN_39 to LEDS[1]
-- PIN_38 to LEDS[0]
-- LCD_E PIN_54 (in pin planner) output
--architecture behave
--reg รับสัญญาณเป็น logic vector 8 bit
--reg_new,D รับสัญญาณเป็น logic (0 or 1)
--in process (CLK) : count is integer range 0 to 50,000 เริ่มที่ count=0

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity LEDSHIFT is
  port( CLK : in std_logic;
        PB : in std_logic;
        LEDs : out std_logic_vector(7 downto 0) );
end LEDSHIFT;

architecture behave of LEDSHIFT is
   signal reg : std_logic_vector(7 downto 0) := "00000001";
   signal reg_new : std_logic;
   signal D : std_logic;
begin
   process(CLK)
      Variable count: Integer range 0 to 50000:=0;
   begin
      if rising_edge(clk) then --ทำงานที่ขอบขาขึ้นของ clk
         if count = 50000 then --ทำงานเมื่อค่า count = 50,000 เพื่อที่จะกดแล้วไม่ข้ามบิต
            if PB = '1' then --เงื่อนไข ถ้ากดปุ่ม PB = 1 ให้ D เก็บค่า PB คือ 1
               D <= PB;
            end if; --จบเงื่อนไข PB = 1
            elsif PB = '0' then --ทำงานเมื่อ PB = 0 (active low)
               reg_new <= (PB xor D); --เปรียบเทียบค่า xor ของ PB กับ D เมื่อต่างกัน reg_new = 1
               if reg_new = '1' then --ทำงานเมื่อ reg_new = 1
                   reg <= reg(6 downto 0) & reg(7);
--shift bit ไปทางซ้าย 1 ตำแหน่ง ค่าซ้ายสุดที่เอาออกไปจะมาเก็บที่ตำแหน่งขวาสุด
                   count:=0; -- reset count variable
               end if; --จบเงื่อนไข reg_new = 1
               D <= PB; --ให้ D เก็บค่า PB คือ 0
            end if;
            count:= count+1; --ให้ค่า count นับเพิ่มขึ้นเรื่อย
        end if; --จบเงื่อนไขขอบขาขึ้น CLK
   end process;
   LED <= reg; --เอาต์พุต รับค่าจาก reg
end behave;



-- File: TB_LEDSHIFT.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity TB_LEDSHIFT is
  -- no ports
end TB_LEDSHIFT;

architecture testbench of TB_LEDSHIFT is
  component LEDSHIFT is
  generic ( counter: Integer := 50000 );
    port(
      CLK : in std_logic;
      PB : in std_logic;
      LEDs : out std_logic_vector(7 downto 0) );
  end component;
  signal t_CLK, t_PB: std_logic;
  signal t_LEDs : std_logic_vector(7 downto 0);
begin
  DUT: LEDSHIFT
    port map (CLK => t_CLK, PB => t_PB, LEDs => t_LEDs );
  process begin -- a process for generating the clock signal (50MHz)
    t_CLK <= '1'; wait for 10 ns;
    t_CLK <= '0'; wait for 10 ns;
  end process;
  process begin -- a process for generating the PB input signal
    t_PB <= '1'; wait for 1 us;
    for i in 0 to 100 loop
      t_PB <= '0'; wait for 1 us;
      t_PB <= '1'; wait for 1 us;
    end loop;
  end process;
end testbench;

--ปล.เนื่องจากเขียนค่า count ใน tb ไม่เป็น ดังนั้นก่อน sim จึงลบค่า count ใน code vhdl ที่ออกแบบ ออกก่อน (-.-)


รูปที่ 1 สร้างวงจรดิจิทัลด้วยภาษา VHDL โดยโปรแกรม Quartus II



รูปที่ 2 กำหนด pin planner สำหรับ FPGA จากโค้ด VHDL


รูปที่ 3 Sim code VHDL ที่ออกแบบ โดยใช้ code testbench


รูปที่ 4 Sim code VHDL ที่ออกแบบ โดยใช้ code testbench

ผลที่ได้จากการ sim คือ เมื่อกดแล้วปล่อย หนึ่งครั้ง LED ที่ติดเลื่อนจาก LEDs(0) ไปหนึ่งตำแหน่งถัดไปคือ LEDs(1) ถ้าเลื่อนไปจนถึง LEDs(7) แล้วจะกลับไปเริ่มที่ LEDs(0)
   - PB เปลี่ยนจาก 0 เป็น 1 มีคาบเวลา 2us
   - LED ติด เมื่อ PB = 0 (active low)


     
รูปที่ 6 ภาพการทดลอง เมื่อ upload code ลงบนบอร์ด FPGA


ไม่มีความคิดเห็น:

แสดงความคิดเห็น