วันจันทร์ที่ 5 มิถุนายน พ.ศ. 2560

Week07 : VHDL - Digital System Laboratory


การเขียนภาษา VHDL สําหรับการออกแบบวงจรดิจิตอล
  • ภาษา VHDL เบื่องต้น 

         VHDL ย่อมาจาก VHSIC Hardware Description language เป็นภาษาบรรยายฮาร์ดแวร์ประเภทหนึ่งโดยเกิดขึ้นจากโครงการที่มีชื่อ VHSIC (Very High Speed Integrate Circuit) โดยมีเป้าหมายของโครงการเพื่อพัฒนาขีดความสามารถในการออกแบบวงจรรวมให้สูงและง่ายมากยิ่งขึ้น ซึ่งมีการพัฒนาจนสามารถกําหนดเป็นมาตรฐานของ IEEE (Institute of Electrical and Electronics Engineers) ได้ในเวลาต่อมา

  • ประโยชน์ของภาษา VHDL

     - เป็นภาษาสากลโดยรองรับจากสถาบัน IEEE ทําให้มีโปรแกรมและเครื่องมือต่างๆ และบริษัทที่
สนับสนุนการทํางานมากมาย
    - เป็นภาษาที่ใช้งานจริงในอุตสาหกรรม
    - ฯลฯ

  • แนะนําพื้นฐานภาษา VHDL
          ภาษา VHDL มีความเป็น Concurrent ซึ่งถือว่าเป็นหัวใจสําคัญของการเขียนออกแบบอุปกรณ์อิเล็กทรอนิกส์หมายถึงการเขียนโค๊ดภาษา VHDL จะไม่มีลําดับความสําคัญของตําแหน่งของแต่ละบรรทัดและภาษา VHDL ยังมีความเป็น Case insensitive อีกด้วยกล่าวคือไม่มีความแตกต่างในการเขียนอักษรพิมพ์เล็กหรือพิมพ์ใหญ์
            ภาษา VHDL สามารถบรรยายพฤติกรรมทางฮาร์ดแวร์ได้หลายระดับ ตั้งแต่การทํางานของวงจร จนถึงระดับลอจิกเกต ซึ่งในแต่ละระดับจะมีรายละเอียดที่แตกต่างกัน เช่น สมมุติผู้ออกแบบต้องการออกแบบวงจรบวกสองอินพุตผู้ออกแบบสามารถออกแบบโดยใช้operatorการบวก (“+”) ในภาษา VHDL หรือทําการออกแบบวงจรในระดับลอจิกเกต หรือทําการออกแบบในระดับทรานซิสเตอร์ก็ได้

  • ค่าหน่วงเวลา (Delta Time)
        เนื่องจากการจําลองการทํางานในระบบ VHDL สามาทํางานแบบ Concurrent ได้กลไกสําคัญที่ช่วยให้การทํางานปราศจากข้อแม้ทางเวลานี้เรียกว่า Delta Time (d-time) และเราไม่ควรเขียนโค้ดที่ทําให้เกิด delta time สะสมมากขึ้นเรื่อยๆ หรือมีค่าไม่รู้จบ เช่น a <= NOT a ; ในกรณีนี้จะทําให้เกิด delta time สะสมจนกระทั่งมีค่าไม่รู้จบ ซึ่งสามารถแก้ไขได้โดยกําหนดค่าหน่วงเวลา เช่น a <= NOT a AFTER 10 us ; ในกรณีนี้จะทําให้เกิดหน่วงการส่งสัญญาณ not a ไปยัง a เป็นเวลา 10 ไมโครวินาที (10-5วินาที) 
  • VHDL Object
                 - ค่าคงที่ (Constant) เป็นออบเจ็กต์ที่เมื่อกําหนดค่าเริ่มต้นแล้วจะคงค่านั้นไว้ตลอดไม่สามารถ
ดัดแปลง หรือแก้ไขได้
       - สัญญาณ (Signal) เป็นออบเจ็กต์ที่สามารถกําหนดค่าที่สัมพันธ์กับเวลานั้น หมายความว่า สัญญาณสามารถรับค่าได้เพียงค่าเดียวเท่านั้นในขณะเวลาหนึ่ง
                - ตัวแปร (Variable) เป็นออบเจ็กต์ที่สามารถกําหนดค่าใดๆได้และสามารถเปลี่ยนแปลงค่าได้
ตลอดเวลาการจําลองการทํางาน แต่จะเก็บค่าได้เพียงค่าเดียวเท่านั้น ในขณะเวลาหนึ่ง และตัวแปรจะสามารถใช้ได้เฉพาะกับการเขียนบรรยายพฤติกรรมแบบลําดับขั้นเท่านั้น กล่าวคือต้องเขียนภายใต้คําสั่ง PROCESS (ซึ่งจะกล่าวในภายหลัง) 
  • การประกาศออบเจ็กต์
          รูปแบบการประกาศออบเจ็กต object name : type := intial_value ; 
              - Object ไดแก constant,signal หรือ variable - Name คือ ชื่อของออบเจ็กต (ซึ่งตองเปนไปตามกฎ) - Type คือการกําหนดประเภทของออบเจ็กต 
         - Intial_value คือการกําหนดคาเริ่มตนสําหรับออบเจ็กตซึ่งอาจจะมีหรือไมก็ได การตั้งชื่อออบเจ็กต
           - ประกอบดวยพยัญชนะตัวเลขและเครื่องหมายขีดเสนใตที่ใชในภาษาอังกฤษไดไมจํากัดจํานวน และตองขึ้นตนดวยพยัญชนะเทานั้น 
            - การใชเครื่องหมายขีดเสนใต(_)ทุกครั้งตองนําหนาและตามดวยพยัญชนะหรือตัวเลขเทานั้น 
            - หามใชคําสงวนในภาษา VHDL (ซึ่งจะกลาวในภายหลัง) 
  • ชนิดของออบเจ็กตที่ไดกําหนดไวแลว
      หมายถึงชนิดของขอมูลที่ไดกําหนดโดย IEEE ในแพกเก็จมาตรฐานดังนั้นจึงไมจําเปนตองประกาศใช ในทุกๆรูปแบบที่เขียนขึ้น
                 - BOOLEAN คือกลุมของตรรกะไดแก TURE และ FALSE 
                 - BIT คือกลุมของคา ‘0’ และ ‘1’
                 - INTEGER คือกลุมของจํานวนเต็มมีคา -214748347 ถึง 214748347 
                 - REAL คือกลุมคาจํานวนเต็มมีคา -1.0E38 ถึง 1.05E38 
                 - CHARATER คือกลุมของพยัญชนะอักษร หรือเครื่องหมายพิเศษ และเครื่องหมายควบคุม 
                 - TIME คือกลุมคาของเวลาซึ่งมีคาพื้นฐานเปนวินาที 
                 - SEVERITY LEVEL คือกลุมคาของการแจงเตือนระดับความรุนแรง เชน warning
  • องคประกอบของภาษา VHDL
         1. Entity เปนหนวยการออกแบบที่ใชสําหรับติดตอระหวางอุปกรณภายนอกกับวงจรที่จะเขียนขึ้น รวมทั้งการสงผานคาพารามิเตอรบางอยางระหวางวงจรกับอุปกรณภายนอก โดยมีรูปแบบ ดังนี้
                                          ENTITY entity_name is 
                                                         GENERIC (generic_list); 
                                                         PORT (port_list); 
                                          END entity_name; 
                  - GENRIC ผูออกแบบสามารถกําหนดคาพารามิเตอรท่ีเปนขอมูลอื่นๆเพิ่มเติมไดในสวนนี้ โดยมีรูปแบบการเขียนดังนี้ 
GENERIC (generic_name : type := intial_value);

                     - PORT ผูออกแบบสามารถประเภทของแตละพอรตไดในสวนนี้โดยมีรูปแบบการเขียนดังนี้

PORT (port_name : port_type); 
                     
                       ประเภทของพอรต(port_type)ที่สามารถประกาศใชใน Entity มี 4 ประเภทดังนี้
                       In (input)       เปนพอรตทิศทางเดียว ที่นําคาจากอุปกรณภายนอกเขามาใชภายในวงจร                                                ได แตไมสามารถถูกเขียนจากภายในวงจรได 
                       Out (output)  เปนพอรตทิศทางเดียว ที่นําคาสัญญาณจากวงจรสงไปยังอุปกรณภายนอก                                              แตไมสามารถถูกอานจากภายในวงจรได 
                      Inout               เปนพอรตสองทิศทาง ที่สามารถถูกเขียนและอานไดภายในวงจร Buffer                                                   เปนพอรตเอาตพุตประเภทหนึ่ง ที่สามารถอาคากลับเขามาภายในวงจรได                                                 (Feedback)

         2. Architecture เปนหนวยออกแบบที่ใชสําหรับเขียนบรรยายพฤติกรรมการทํางานของวงจรที่ตองการ ออกแบบ ซึ่งจะสัมพันธกับสวนของEntity โดยมีรูปแบบการเขียนดังนี้
                                           ARCHITECTURE arch_name of entity_name is 
                                                           Signal_declalarations 
                                                           Constant_declalarations 
                                          BEGIN 
                                                          - The program; 
                                          END arch_name; 

  • คําสั่งตางๆ ภายในภาษา VHDL
             ตัวดําเนินการในภาษา VHDL ภาษา VHDL จะมีชุดของ 0perator ที่ใชสําหรับการเปรียบเทียบการกระทําการทางคณิตศาสตรหรือ ตรรกะโดยชุดของ Operator ทั้งหมดของภาษา VHDL มีดังตอไปนี้ 

                                                 NOT                    Inversion 
                                                 AND                    And function 
                                                NAND                 Not-and function 
                                                OR                       Or function 
                                                NOR                    Not-or function 
                                                XOR                    Exclusive-or function (bit wise inequality) 
                                                XNOR                 Exclusive-nor function (bit wise equality)(VHDL’93) 
                                                =                          Equality 
                                                /=                         Inequality 
                                                >=                        Greater-than or equality 
                                                >                          Greater-than 
                                                <=                        Less-than or equality 
                                                <                          Less-than 
                                               SLL                      Shift-left logical (VHDL’93) 
                                               SRL                      Shift-right logical (VHDL’93) 
                                               SLA                      Shift-left arithmetic (VHDL’93) 
                                               SRA                     Shift- right arithmetic (VHDL’93) 
                                               ROL                     Rotate left (VHDL’93) 
                                               ROR                     Rotate right (VHDL’93) 
                                               +                           Addition 
                                               -                            Minus sign 
                                              *                            Multiplication 
                                              /                             Division 
                                              MOD                     Modulo arithmetic 
                                              REM                     Remainder after division 
                                              **                          Exponentiation 
                                              ABS                      Absolute value 
                                              &                          Concatenation
  • การทํางานของ operator
               สามารถแบง Operator เปนกลุม โดยมีลําดับการทํางานของ operator จากสูงไปต่ำไดดังนี้ 

                                     กลุมพิเศษ ** ,ABS ,NOT 
                                     กลุมการคูณ * ,/ ,MOD ,REM 
                                     กลุมการบวก + ,- ,& 
                                     กลุมการเลื่อนบิต SLL ,SRL ,SLA ,SRA ,ROL ,ROR 
                                     กลุมความสัมพันธ = ,/= ,>= ,> ,<= ,< 
                                     กลุมตรรกะ AND ,OR ,NAND ,NOR ,XOR ,XNOR
          
        การทํางานของ operator จะเริ่มทํางานที่ operator ที่มีลําดับการทํางานสูงสุดไปต่ำสุด สําหรับ operator ที่มีลําดับการทํางานระดับเดียวกันจะทํางานจากซายไปขวา เชน 1-2+3*4 จะหมายถึง 1-2+(3*4) = 1-2+12 = (1- 2)+12 = -1+12 = 11 

  • การกําหนดคาตางๆ
               การเขียน comment จะใชเครื่องหมาย -- แลวตามดวยขอความ 
           การกําหนดคาสัญญาณจะใชเครื่องหมาย <= โดยจะใหสัญญาณที่ตองการใหรับคาอยูดานขวาของเครื่องหมายและสัญญาณที่ตองการใหสงคา(อาจจะอยูในรูปของสมการหรือการดําเนินการตางๆ)อยูดานซายของ เครื่องหมาย เชน q <= a or b ; หมายความวาจะสงคาที่ไดจาก a or b ไปยัง q และเมื่อมีกําหนดคาใหกับสัญญาณ (signal assignment) สัญญาณจะมีการเปลี่ยนแปลงคาโดยใชเวลาอยางนอย 1 delta time เสมอ 
             การกําหนดคาตัวแปรจะใชเครื่องหมาย := โดยการกําหนดตัวแปรสามารถใชไดเฉพาะภายใน คําสั่ง process เทานั้น และจะใหตัวแปรที่ตองการใหรับคาอยูดานขวาของเครื่องหมายและตัวแปรที่ตองการใหสง คา(อาจจะอยูในรูปของสมการหรือการดําเนินการตางๆ)อยูดานซายของเครื่องหมาย เชน y := m*x + c ; หมายความวา จะสงคาที่ไดจากสมการ (m คูณ x) บวก c ไปยังตัวแปร y และเมื่อมีกําหนดคาใหกับตัวแปร (variable assignment) ตัวแปรจะมีการเปลี่ยนแปลงคาทันที 






กฎการใชคําสั่ง case 
       • ตัวเลือก (choice) จะตองเปนแบบระบุตัวเลือกที่เปนคาแนนอน 
       • ถามีมากวา 1 ตัวเลือกจะใชเครื่องหมาย | ซึ่งมีความหมายวา or 
       • ถาตองการระบุเปนชวงขอมูล สามารถใชคําสั่ง TO ได 
       • “WHEN OTHERS” จะใชเปนตัวเลือกครอบคลุมที่เหลือทั้งหมด ขอควรระวังการใชคําสั่ง case 
       • เงื่อนไขตองไมขัดแยงกัน 
       • ตองกําหนดตัวเลือกครบทุกกรณี



  • คําสงวนในภาษา VHDL 
            การตั้งชื่อตางๆในภาษา VHDL ตามมาตรฐาน IEEE มีขอจํากัดในการใชคําสงวน (reserved word) ที่ไม สามารถนําไปเปนชื่อตางๆไดในทุกลักษณะของตัวหนังสือคําเหลานี้ไดแก




แบบฝึกหัด การโปรแกรมด้วยภาษา VHDL







523274 Digital System Laboratory 1(0-3-0)
มหาวิทยาลัยเทคโนโลยีสุรนารี
รหัส B5711826 เลขที่นั่ง PC = 3
สำนักวิชาวิศวกรรมศาสตร์
ชื่อ-สกุล นางสาว ไอลดา พลพฤกษ์
สาขาวิชาวิศวกรรมคอมพิวเตอร์
วันที่ 02 เดือน มิถุนายน .. 2560

Lab 10 การโปรแกรมด้วยภาษา VHDL < เก็บไว้ตรวจ >


เตรียมการทดลอง
1.  Read this “ISE_10 Start Verilog.pdf”
2.  Read this “ISE 11_1 Encoder Tutorial - VHDL Verilog.pdf”

การทดลอง
1. ปรับวงจรนับเป็น Up-Down Counter 4 bit โดยมี สัญญาญ CU ควบคุมการนับ ทดสอบร่วมกับ 7_Segment Encoder ที่สร้างขึ้นจากข้อ 2 การแสดงผลระหว่าง 0 - F
·         C ควบคุมการนับและหยุดนับ        ถ้าเป็น 1 ให้นับต่อ      ถ้าเป็น 0 ให้หยุดนับ
·         U ควบคุมทิศทางการนับ      ถ้าเป็น 1 ให้นับขึ้น      ถ้าเป็น 0 ให้นับลง

VHDL-Code
------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
entity Encoder is
    Port ( B : in  STD_LOGIC;
           A : in  STD_LOGIC;
           F : out  STD_LOGIC_VECTOR (3 downto 0));
end Encoder;
 
architecture Behavioral of Encoder is
 
begin
        F <=    "0001" when (B='0' and A='0') else  
               "0010" when (B='0' and A='1') else  
               "0100" when (B='1' and A='0') else  
               "1000" ;  
        
end Behavioral;

ตัวอย่าง Code ที่ทำในคาบเรียน

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Counter is
                Port (     Clk                       : in  STD_LOGIC;
                                Enable                 : in  STD_LOGIC;
                                UpDown              : in  STD_LOGIC;
                                Reset : in  STD_LOGIC;
                                Output                 : out  STD_LOGIC_VECTOR (6 downto 0));
end Counter;
architecture Behavioral of Counter is
signal pre_count: std_logic_vector(3 downto 0);
begin
               process(Clk,Reset, Enable, UpDown)
                begin
                                if Reset = '1' then
                                    pre_count<= "0000";
                                elsif(Clk='1' and Clk'event) then
                                     if Enable='1' then
                                     if UpDown='1' then
                                     pre_count<= pre_count + "1";
                                     else
                                     pre_count<= pre_count - "1";
                                    end if;
                                    end if;
                              end if;
                end process; 
                Output<=  "1111110" when pre_count="0000" else
                                            "0110000"when pre_count ="0001" else
                   "1101101"when pre_count ="0010" else
                                            "1111001"when pre_count ="0011" else
                                            "0110011"when pre_count ="0100" else
                                            "1011011"when pre_count ="0101" else
                                            "1011111"when pre_count ="0110" else
                                            "1110000"when pre_count ="0111" else
                                            "1111111"when pre_count ="1000" else
                                            "1111011"when pre_count ="1001" else
                                            "1110111"when pre_count ="1010" else
                                            "0011111"when pre_count ="1011" else
                                            "1001110"when pre_count ="1100" else
                                            "0111101"when pre_count ="1101" else
                                            "1001111"when pre_count ="1110" else
                                            "1000111";
end Behavioral;
วีดีโอตัวอย่างที่ทำในคาบเรียน





ขั้นตอนดำเนินงานด้วย ISE 14.2
1.      1. New Project





Family            XC9500 CPLDs
Device            XC9572
Package        PC44






 2.New Source




B          in
A          in
F          out       þ       3          0




-- Coding
architecture Behavioral of Encoder is
begin
            F <=    "0001" when (B='0' and A='0') else 
                        "0010" when (B='0' and A='1') else 
                        "0100" when (B='1' and A='0') else 
                        "1000" ; 
end Behavioral;



Inplement All



3.       3.Assigned Pin









Inplement All


4.     4.  Lode Program










Select file XXXX.jed
Opertation à Program



2. ใช้ Xilinx ISE 14.4 ด้วยโปรแกรม VHDL ในการสร้าง 7_Segment Encoder
Helper
Above figure shows seven segment LED display. These are widely used in Digital clocks and at Traffic islands. BCD data can’t be displayed directly on this display. So a code converter is needed. This code converter takes BCD data and produces data in a format to display the corresponding BCD number.
To display BCD number 1, b and c LEDs (shown in above figure) should glow and remaining should be in turn off state. Similarly for remaining numbers same technique is applied. The truth table for this is shown below.


            Truth table:








          VHDL program for BCD to 7-segment decoder: 



·       ตัวอย่างนี้ใช้ Switch Case
·       แต่เฉลยใช้ if – else if – else



ปรับแก้ให้แสดงผล ดังนี้









< ให้เติมค่าในตารางให้ครบ >
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Encoder is

Port (      Inport : in STD_LOGIC_VECTOR (3 downto 0);
                        Outport : out STD_LOGIC_VECTOR (6 downto 0));
end Encoder;

architecture Behavioral of Encoder is

begin
Outport <= "1111110" when Inport ="0000" else
                        "0110000" when Inport ="0001" else
                        "1101101" when Inport ="0010" else
                        "1111001" when Inport ="0011" else
                        "0110011" when Inport ="0100" else
                        "1011011" when Inport ="0101" else
                        "1011111" when Inport ="0110" else
                        "1110000" when Inport ="0111" else
                        "1111111" when Inport ="1000" else
                        "1111011" when Inport ="1001" else
                        "1110111" when Inport ="1010" else
                        "0011111" when Inport ="1011" else
                        "1001110" when Inport ="1100" else
                        "0111101" when Inport ="1101" else
                        "1001111" when Inport ="1110" else
                        "1000111" ;

 end Behavioral;



3. จากโปรแกรมนับขึ้น 4 บิตด้วย VHDL ทดสอบกับ LED Logic Monitor 4 ดวง ให้ปรับปรุงโปรแกรมนี้เพื่อนับแบบเลข 8 บิต ทดสอบร่วมกับ 7_Segment Encoder ที่สร้างขึ้นจากข้อ 2 การแสดงผลจะเริ่มจาก 00 - FF
Helper
VHDL Code - 4Bit Up Counter from 0000 to 1111
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Counter is
            Port (   clk : in  STD_LOGIC;
                        reset : in  STD_LOGIC;
                        Output : out  STD_LOGIC_VECTOR (3 downto 0));
end Counter;

architecture Behavioral of Counter is
signal pre_count: std_logic_vector(3 downto 0);
begin
            process(clk, reset)
            begin
                        if reset = '1' then
                                    pre_count <= "0000";
                        elsif (clk='1' and clk'event) then
                                    pre_count <= pre_count + "1";
                        end if;
            end process; 
            Output <= pre_count;
end Behavioral;

VHDL Code – 8Bit Counter from 00 to FF

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Counter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
Outport : out STD_LOGIC_VECTOR (6 downto 0);
Outport2 : out STD_LOGIC_VECTOR (6 downto 0));
end Counter;
architecture Behavioral of Counter is
signal pre_count: std_logic_vector(3 downto 0);
signal pre_count2: std_logic_vector(3 downto 0);
begin
process(clk, reset)
begin
if reset = '1' then
pre_count <= "0000";
elsif (clk='1' and clk'event) then
pre_count <= pre_count + "1";
if pre_count = "1111" then
pre_count2 <= pre_count2 + "1";
end if;
end if;
end process;
Outport <= "1111110" when pre_count ="0000" else
"0110000" when pre_count ="0001" else
"1101101" when pre_count ="0010" else
"1111001" when pre_count ="0011" else
"0110011" when pre_count ="0100" else
"1011011" when pre_count ="0101" else
"1011111" when pre_count ="0110" else
"1110000" when pre_count ="0111" else
"1111111" when pre_count ="1000" else
"1111011" when pre_count ="1001" else
"1110111" when pre_count ="1010" else
"0011111" when pre_count ="1011" else
"1001110" when pre_count ="1100" else
"0111101" when pre_count ="1101" else
"1001111" when pre_count ="1110" else
"1000111" ;
Outport2 <= "1111110" when pre_count2 ="0000" else
"0110000" when pre_count2 ="0001" else
"1101101" when pre_count2 ="0010" else
"1111001" when pre_count2 ="0011" else
"0110011" when pre_count2 ="0100" else
"1011011" when pre_count2 ="0101" else
"1011111" when pre_count2 ="0110" else
"1110000" when pre_count2 ="0111" else
"1111111" when pre_count2 ="1000" else
"1111011" when pre_count2 ="1001" else
"1110111" when pre_count2 ="1010" else
"0011111" when pre_count2 ="1011" else
"1001110" when pre_count2 ="1100" else
"0111101" when pre_count2 ="1101" else
"1001111" when pre_count2 ="1110" else
"1000111" ;
end Behavioral;

วีดีโอตัวอย่างที่ทำในคาบเรียน









4.
ปรับวงจรนับเป็น Up-Down Counter 4 bit โดยมี สัญญาญ CU ควบคุมการนับ ทดสอบร่วมกับ 7_Segment Encoder ที่สร้างขึ้นจากข้อ 2 การแสดงผลระหว่าง 0 - F
·         C ควบคุมการนับและหยุดนับ        ถ้าเป็น 1 ให้นับต่อ      ถ้าเป็น 0 ให้หยุดนับ
·         U ควบคุมทิศทางการนับ      ถ้าเป็น 1 ให้นับขึ้น      ถ้าเป็น 0 ให้นับลง
Helper
·         https://forums.xilinx.com/t5/General-Technical-Discussion/7-segment-display-with-a-clock-counter/td-p/436948
VHDL Code - 4Bit Counter with Control (0000 - 1111)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Counter is
        Port (       Clk                   : in  STD_LOGIC;
                        Enable              : in  STD_LOGIC;
                        UpDown           : in  STD_LOGIC;
                        Reset               : in  STD_LOGIC;
                        Output             : out  STD_LOGIC_VECTOR (3 downto 0));
end Counter;

architecture Behavioral of Counter is
signal pre_count: std_logic_vector(3 downto 0);
begin
            process(Clk, Reset, Enable, UpDown)
            begin
                        if Reset = '1' then
                                    pre_count <= "0000";
                        elsif (Clk='1' and Clk'event) then
                                    if Enable='1' then
                                                if UpDown='1' then
                                                            pre_count <= pre_count + "1";
                                                else
                                                            pre_count <= pre_count - "1";
                                                end if;
                                    end if;
                        end if;
            end process; 
            Output <= pre_count;
end Behavioral;

VHDL Code – 4Bit Counter from 0 to F

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Counter is
 Port ( Clk   : in  STD_LOGIC;
  Enable  : in  STD_LOGIC;
  UpDown : in  STD_LOGIC;
  Reset   : in  STD_LOGIC;
  Output  : out  STD_LOGIC_VECTOR (6 downto 0));
end Counter;

architecture Behavioral of Counter is
signal pre_count: std_logic_vector(3 downto 0);
begin
 process(Clk, Reset, Enable, UpDown)
 begin
  if Reset = '1' then
   pre_count <= "0000";
  elsif (Clk='1' and Clk'event) then
   if Enable='1' then
    if UpDown='1' then
     pre_count <= pre_count + "1";
    else
     pre_count <= pre_count - "1";
    end if;
   end if;
  end if;
 end process;  
 Output <=  "1111110" when pre_count ="0000" else
     "0110000" when pre_count ="0001" else
     "1101101" when pre_count ="0010" else
     "1111001" when pre_count ="0011" else
     "0110011" when pre_count ="0100" else
     "1011011" when pre_count ="0101" else
     "1011111" when pre_count ="0110" else
     "1110000" when pre_count ="0111" else
     "1111111" when pre_count ="1000" else
     "1111011" when pre_count ="1001" else
     "1110111" when pre_count ="1010" else
     "0011111" when pre_count ="1011" else
     "1001110" when pre_count ="1100" else
     "0111101" when pre_count ="1101" else
     "1001111" when pre_count ="1110" else
     "1000111" ;
end Behavioral;

วีดีโอตัวอย่างที่ทำในคาบเรียน






เมื่อรันจะได้ตัวอย่างดังวีดีโอ













5. ออกแบบ ALU โดยใช้ VHDL ให้มี Output F[3..0] และ Input A[1..0], B[1..0], C[2..0] กำหนดให้ทำงาน ดังนี้
C[2..0]
Logic Function

C[2..0]
Math Function
000
F=

100
F = A plus B
001
F = A OR B

101
F = A minus B
010
F = A AND B

110
F = -A
011
F = A XOR B

111
F = A plus 1

Helper
VHDL-Code

--Sample 5
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Use ieee.std_logic_unsigned.all;
Use ieee.std_logic_arith.all; 
use IEEE.NUMERIC_STD.ALL;
entity Sample5 is
Port ( C : in STD_LOGIC_VECTOR (2 downto 0);
iA : in STD_LOGIC_VECTOR (1 downto 0);
iB : in STD_LOGIC_VECTOR (1 downto 0);
F : out STD_LOGIC_VECTOR (3 downto 0));
end Sample5;
architecture Behavioral of Sample5 is
signal pre: std_logic_vector(3 downto 0);
signal InA: std_logic_vector(3 downto 0);
signal InB: std_logic_vector(3 downto 0);
begin
InA(1 downto 0) <= IA(1 downto 0);
InB(1 downto 0) <= IB(1 downto 0);
process(C,IA,IB)
begin
if(C="000") then pre <= not InA;
elsif(C="001") then pre <= InA or InB;
elsif(C="010") then pre <= InA and InB;
elsif(C="011") then pre <= InA xor InB;
elsif(C="100") then pre <= InA + InB;
elsif(C="101") then pre <= InA - InB;
elsif(C="110") then pre <= (not InA)+1;
else pre <= InA + 1;
end if ;
end process;
F <= pre;
end Behavioral;