วันอาทิตย์ที่ 5 เมษายน พ.ศ. 2558

การทดลองที่ 6


การทดลองที่ 6
การใช้ IP core สำหรับ 16x2 LCD เพื่อแสดงข้อความ "Hello World!"

วัตถุประสงค์
1.เพื่อเพิ่มความเข้าใจเกี่ยวกับการแสดงผลบน LCD 16x2 บน FPGA มากขึ้น
2.สามารถเขียน code VHDL สั่งงานให้ข้อความที่กำหนดไปแสดงผลบนจอได้อย่างถูกต้อง
3.สามารถประยุกต์ความรู้ที่ได้เข้ากับวงจรอื่นๆได้อย่างเหมาะสม

โจทย์การทดลอง
เขียน VHDL เพื่อสั่งงานวงจรให้แสดงข้อความ "Hello World" บน 16x2 LCD ผ่านทาง IP Core

อุปกรณ์
1.บอร์ด FPGA CYCLOne 3 ชิปหมายเลข EP3C10E144C8 1 บอร์ด




2. ออสซิโลสโคป 1 เครื่อง




3. สายไฟ

4. คอมพิวเตอร์ที่มีโปรแกรม Altera 10.1d (Quartus II 13.1)


โค้ดการทดลอง
library ieee;
use ieee.std_logic_1164.all;

entity lcd16x2_ctrl_demo is
  port (
    clk    : in  std_logic;
    lcd_e  : out std_logic;
    lcd_rs : out std_logic;
    lcd_rw : out std_logic;
    lcd_db : out std_logic_vector(7 downto 4));
end entity lcd16x2_ctrl_demo;

architecture behavior of lcd16x2_ctrl_demo is
  signal timer : natural range 0 to 100000000 := 0;
  signal switch_lines : std_logic := '0';
  signal line1 : std_logic_vector(127 downto 0);
  signal line2 : std_logic_vector(127 downto 0);

  constant CLK_PERIOD_NS : positive := 10;  -- 100 Mhz

  signal rst          : std_logic;
  signal line1_buffer : std_logic_vector(127 downto 0);
  signal line2_buffer : std_logic_vector(127 downto 0);
begin
  DUT : entity work.lcd16x2_ctrl
    generic map (
      CLK_PERIOD_NS => CLK_PERIOD_NS)
    port map (
      clk          => clk,
      rst          => rst,
      lcd_e        => lcd_e,
      lcd_rs       => lcd_rs,
      lcd_rw       => lcd_rw,
      lcd_db       => lcd_db,
      line1_buffer => line1_buffer,
      line2_buffer => line2_buffer);

  rst <= '0';

  -- see the display's datasheet for the character map
  line1(127 downto 120) <= X"20";
  line1(119 downto 112) <= X"20";
  line1(111 downto 104) <= X"48";  -- H
  line1(103 downto 96)  <= X"65";  -- e
  line1(95 downto 88)   <= X"6c";  -- l
  line1(87 downto 80)   <= X"6c";  -- l
  line1(79 downto 72)   <= X"6f";  -- o
  line1(71 downto 64)   <= X"20";
  line1(63 downto 56)   <= X"57";  -- W
  line1(55 downto 48)   <= X"6f";  -- o
  line1(47 downto 40)   <= X"72";  -- r
  line1(39 downto 32)   <= X"6c";  -- l
  line1(31 downto 24)   <= X"64";  -- d
  line1(23 downto 16)   <= X"21";  -- !
  line1(15 downto 8)    <= X"20";
  line1(7 downto 0)     <= X"20";

  line2(127 downto 120) <= X"30";
  line2(119 downto 112) <= X"31";
  line2(111 downto 104) <= X"32";
  line2(103 downto 96)  <= X"33";
  line2(95 downto 88)   <= X"34";
  line2(87 downto 80)   <= X"35";
  line2(79 downto 72)   <= X"36";
  line2(71 downto 64)   <= X"37";
  line2(63 downto 56)   <= X"38";
  line2(55 downto 48)   <= X"39";
  line2(47 downto 40)   <= X"3a";
  line2(39 downto 32)   <= X"3b";
  line2(31 downto 24)   <= X"3c";
  line2(23 downto 16)   <= X"3d";
  line2(15 downto 8)    <= X"3e";
  line2(7 downto 0)     <= X"3f";

  line1_buffer <= line2 when switch_lines = '1' else line1;
  line2_buffer <= line1 when switch_lines = '1' else line2;

  -- switch lines every second
  process(clk)
  begin
    if rising_edge(clk) then
      if timer = 0 then
        timer <= 100000000;
        switch_lines <= not switch_lines;
      else
        timer <= timer - 1;
      end if;
    end if;
   
  end process;
end architecture behavior;





Test Bench

library ieee;
use ieee.std_logic_1164.all;

entity lcd16x2_ctrl_tb is
end entity lcd16x2_ctrl_tb;

architecture behavior of lcd16x2_ctrl_tb is
  constant CLK_PERIOD_NS : positive := 20;

  signal clk          : std_logic := '1';
  signal rst          : std_logic;
  signal lcd_e        : std_logic;
  signal lcd_rs       : std_logic;
  signal lcd_rw       : std_logic;
  signal lcd_db       : std_logic_vector(3 downto 0);
  signal line1_buffer : std_logic_vector(127 downto 0);
  signal line2_buffer : std_logic_vector(127 downto 0);

begin

  DUT: entity work.lcd16x2_ctrl
    generic map (
      CLK_PERIOD_NS => CLK_PERIOD_NS)
    port map (
      clk          => clk,
      rst          => rst,
      lcd_e        => lcd_e,
      lcd_rs       => lcd_rs,
      lcd_rw       => lcd_rw,
      lcd_db       => lcd_db,
      line1_buffer => line1_buffer,
      line2_buffer => line2_buffer);

  -- clock generation
  Clk <= not Clk after 10 ns;
  rst <= '0';
  line1_buffer <= (others => '1');
  line2_buffer <= (others => '0');

  -- waveform generation
  WaveGen_Proc: process
  begin
    -- insert signal assignments here
 
    wait until Clk = '1';
  end process WaveGen_Proc;

end architecture behavior;

configuration lcd16x2_ctrl_tb_behavior_cfg of lcd16x2_ctrl_tb is
  for behavior
  end for;
end lcd16x2_ctrl_tb_behavior_cfg;


ผลการจำลองการทำงานโดยโปรแกรม Model Sim


ภาพการทดลอง



ภาพจอแสดงผลตัวอักษร "Hello Word "

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

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