VHDL Learning LOGIC DESIGN WITH VHDL VHDL Learning 一、What is VHDL ? V HSIC (Very High Speed Integrated Circuit) Hardware Description Language VHDL is a Design Description Language VHDL is a Design Documentation Language VHDL is a Simulation Language It is an IEEE Standard Language (IEEE1076 & 1164) VHDL Learning 2、Why Use VHDL? Very Fast Time-to-Market Allows designers to quickly develop designs requiring tens of thousands of logic gates or more Provides powerful high-level constructs for describing complex logic Supports modular design methodology and multiple levels of hierarchy One language for design and simulation Allows creation of device-independent designs that are portable to multiple PLD vendors Allows user to pick any synthesis tool, vendor, or device VHDL Learning 二、VHDL Design Descriptions VHDL design descriptions consist of an ENTITY declaration and an ARCHITECTURE body The ENTITY declaration describes the design I/O The ARCHITECTURE body describes the content or function of the design Every architecture needs an entity so it is common to refer to them together as an ENTITY/ARCHITECTURE PAIR VHDL Learning 1、The Entity A “BLACK BOX” The ENTITY describes the I/O of the black box BLACK_BOX rst q[7:0] d[7:0] clk co VHDL Learning Example Entity declaration ENTITY black_box IS PORT ( clk, rst: IN std_logic; d: IN std_logic_vector(7 DOWNTO 0); q: OUT std_logic_vector(7 DOWNTO 0); co: OUT std_logic); END black_box; BLACK_BOX What does it all mean ? rst q[7:0] d[7:0] clk co VHDL Learning (2)Ports The Entity (“BLACK BOX”) has PORTS PORTS are the points of communication • PORTS are usually the device pins PORTS have an associated name, mode, and type VHDL Learning (3)Port Modes A port’s MODE indicates the direction that data is transferred: Entity IN Data goes into the entity only OUT Data goes out of the entity only (and is not used internally) INOUT Data is bi-directional (goes into and out of the entity) BUFFER Data that goes out of the entity and is also fed-back internally VHDL Learning (4)IEEE 1076 Types Every port on the entity has a Type. The type is always checked during an assignment or comparison. BIT - a port of type bit that can only take values of '0' or '1' BIT_VECTOR - a grouping of bits (each can be '0' or '1') ENTITY type_example IS PORT ( a: IN b: OUT c: OUT BIT; BIT_VECTOR(0 TO 3); BIT_VECTOR(3 DOWNTO 0); -- ascending range -- descending range END type_example; b <= c <= This means that: "0111"; "0101"; b(0) b(1) b(2) b(3) = = = = -- Note: <= is an assignment -- double quotes (“”) used for vectors '0' '1' '1' '1' c(0) c(1) c(2) c(3) = = = = '1' '0' '1' '0' VHDL Learning IEEE 1076 Types (contd.) INTEGER • useful as index holders for loops, constants, arithmetic functions, or simulation modeling BOOLEAN • can take values ‘TRUE’ or ‘FALSE’ ENUMERATED • has user defined set of possible values. e.g.: TYPE traffic_light IS (red, yellow, green); VHDL Learning IEEE 1164 A package created to solve the limitations of the BIT type Nine values instead of just two ('0' and '1') Allows increased flexibility in VHDL coding, synthesis, and simulation STD_LOGIC and STD_LOGIC_VECTOR are used instead of BIT and BIT_VECTOR when a multi-valued logic system is required STD_LOGIC and STD_LOGIC _VECTOR must be used when tri-state logic (Z) is required To be able to use this new type, you need to add 2 lines to your code: LIBRARY ieee; USE ieee.std_logic_1164.ALL; VHDL Learning IEEE-1164 Types STD_LOGIC and STD_LOGIC_VECTOR are now the industry standard logic type for digital design All 9 values are valid in a VHDL simulator, however only: ‘0’ -- Hard ‘0’ ‘1’ -- Hard ‘1’ ‘Z’ -- High Impedance ‘L’ -- Weak ‘0’ (like resistor pull down) ‘H’ -- Weak ‘1’ (like resistor pull up) ‘-’ -- Don’t care are recognized for logic synthesis VHDL Learning Entity Declaration Example LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY black_box IS PORT ( clk, rst: IN std_logic; d: IN std_logic_vector(7 DOWNTO 0); q: OUT std_logic_vector(7 DOWNTO 0); co: OUT std_logic); END black_box; BLACK_BOX MODE TYPE rst q[7:0] d[7:0] co clk VHDL Learning Exercise #1: The Entity Write an entity declaration for the following: Port D is a 12-bit bus, input only Port OE and CLK are each input bits Port AD is a 12-bit bi-directional bus Port A is a 12-bit bus, output only Port INT is an output Port AS is an output also used internally my_design d[11:0] oe clk ad[11:0] a[11:0] int as VHDL Learning Exercise #1: Solution LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY my_design IS PORT ( d: IN std_logic_vector(11 DOWNTO 0); oe, clk: IN std_logic; ad: INOUT std_logic_vector(11 DOWNTO 0); a: OUT std_logic_vector(11 DOWNTO 0); int: OUT std_logic; as: BUFFER std_logic); END my_design; my_design -- In this presentation, VHDL keywords ad[11:0] d[11:0] -- are highlighted in bold, CAPITALS. a[11:0] oe -- However, VHDL is not case sensitive: int clk -- clock, Clock, CLOCK all refer to the as -- same signal VHDL Learning 3、The Architecture Architectures describe what is in the black box (i.e. the function or behavior of entities) Descriptions can be either a combination of Structural descriptions (结构描述) • Instantiations of building blocks (placement of componentsjust like a schematicand their connections) Behavioral descriptions (行为描述) • Algorithmic (or “high-level”) descriptions: IF a = b THEN state <= state5; • Boolean equations: x <= (a OR b) AND c; VHDL Learning Behavioral Architecture Example 8x 2 Input AND gate: ENTITY black_box IS PORT ( a, b: IN y: OUT END black_box; std_logic_vector(7 DOWNTO 0); std_logic_vector(7 DOWNTO 0)); ARCHITECTURE example OF black_box IS BEGIN y <= a AND b; END example; This example shows how to drive the device pins (the entity ports). How do we handle internal signals (or nets) that do not connect directly to the device pins ? VHDL Learning 4、Signals Typically used to represent wires (or nets) Entity Ports are a special type of signal Like ports, they have a name and type (however, there is no mode) Signals are declared inside the architecture before the BEGIN For Example, to create an internal 4 bit bus: ARCHITECTURE signal_example OF black_box IS SIGNAL count: std_logic_vector (3 DOWNTO 0); BEGIN .. <Many VHDL Statements> END signal_example; VHDL Learning 三、Combinatorial Logic There are many ways to describe combinatorial circuits In the next few slides, we will take a look at some examples of how to describe combinatorial logic You should refer back to these slides for some ideas when you start writing your first designs VHDL Learning 1、VHDL Statement Examples (1) Boolean Equations All standard Boolean operators are supported in VHDL AND, OR, NOT, XOR, XNOR, NAND For example, a 4-1 multiplexer is shown below A x <= (d0 (d1 (d2 (d3 AND AND AND AND NOT(A(1)) AND NOT(A(0))) OR NOT(A(1)) AND A(0)) OR A(1) AND NOT(A(0))) OR A(1) AND A(0)) ; 2 d0 d1 d2 d3 Y D0 m0 D1m1 D2 m2 D3m3 D0 A1 ' A0 ' D1 A1 A0 ' D2 A1 A0 ' D3 A1 A0 mux x VHDL Learning 2、VHDL Statement Examples (2) WITH-SELECT-WHEN Assignment based on a selection signal WHEN clauses must be mutually exclusive (all different) Always use “WHEN OTHERS” to cover unspecified cases Only one reference to the signal, only one assignment operator (<=) WITH selection_signal SELECT signal_name <= value_1 WHEN value_1 of selection_signal, value_2 WHEN value_2 of selection_signal, ... value_n WHEN value_n of selection_signal, value_x WHEN OTHERS; VHDL Learning VHDL Statement Examples (2) WITH-SELECT-WHEN The same 4-1 multiplexer we saw earlier could also be described as follows: WITH A SELECT x <= d0 WHEN d1 WHEN d2 WHEN d3 WHEN A “00”, -- means when A=“00” “01”, d0 “10”, d1 OTHERS; d2 d3 2 mux x VHDL Learning VHDL Statement Examples (2) WITH-SELECT-WHEN There can be multiple conditions on each line: WITH s SELECT x <= a WHEN ”000” | “001” | “010”, b WHEN "101" | "111", -- ‘|’ means “or” in this case c WHEN OTHERS; VHDL Learning VHDL Statement Examples (3) WHEN- ELSE Signal is assigned a value based on conditions Any simple expression can be a condition Priority goes in order of appearance Only one reference to the signal, only one assignment operator (<=) Always end with ELSE to cover unspecified conditions signal_name <= value_1 WHEN condition1 ELSE value_2 WHEN condition2 ELSE ... value_n WHEN conditionn ELSE value_x; VHDL Learning VHDL Statement Examples (3) WHEN-ELSE The same example 4-1 multiplexer could also be described as follows: A x <= d0 d1 d2 d3 when (A = “00”) else when (A = “01”) else when (A = “10”) else ; 2 d0 d1 d2 d3 mux x VHDL Learning VHDL Statement Examples (3) WHEN-ELSE What is the difference between WITH-SELECT-WHEN and WHEN-ELSE ? WITH-SELECT-WHEN allows only one control signal WHEN-ELSE supports many different control signals Example: A priority encoder j <= w when x when y when z when ‘0’ ; (a (b (c (d = = = = ‘1’) ‘1’) ‘1’) ‘1’) else else else else VHDL Learning 四、VHDL Statements There are two types of statements, Concurrent and Sequential Concurrent Statements (means in parallel) Concurrent statements are “executed” concurrently (at the same time) The examples we have seen so far are all concurrent statements: – Boolean Equations – WHEN-ELSE – WITH-SELECT-WHEN The order of concurrent statements is not important VHDL Learning The order of concurrent statements For example, suppose we had the following 2 lines of code: x <= a AND b; y <= x NAND C; This will produce exactly the same result as: y <= x NAND C; x <= a AND b; The order that you write the statements makes no difference, because they are concurrent (working in parallel) VHDL Learning 2、VHDL Statements (cont.) Sequential Statements (means in series) Sometimes we need to model complex functions. In that case, we can use an “algorithm” or a model to describe the function. This is done with Sequential Statements With Sequential statements, the ORDER of the statements is important (example later) Therefore, we use a process to mark the beginning and end of a block of sequential statements Each completed process is considered to be one big concurrent statement (there can be many processes inside one architecture) VHDL Learning 3、What is a VHDL “Process” ? Processes are either awake or asleep (active or inactive) A process normally has a sensitivity list(敏感参数表) When a signal in that sensitivity list changes value, the process wakes up and all of the sequential statements are “executed” For example, a process with a clock signal in its sensitivity list will become active on changes of the clock signal At the end of the process, all the outputs are updated and the process goes back to sleep until the next time a signal changes in the sensitivity list VHDL Learning The Process: An Example mux: PROCESS (a, b, s) BEGIN IF s = '0' THEN x <= a; ELSE x <= b; END IF; END PROCESS mux; s a(3 DOWNTO 0) x(3 DOWNTO 0) b(3 DOWNTO 0) The process mux is sensitive to signals a, b, and s. That means that whenever any of those signals changes value, the process wakes up, the sequential statements are executed and the output x is updated Note 1: The logic could be registered (synchronous) or combinatorial Note 2: The order of the signals in the sensitivity list is not important VHDL Learning 4、Combinatorial Logic using Sequential Statements We have already looked at some examples of combinatorial logic using Concurrent Statements Let’s take a look at how to create combinatorial logic with sequential statements... VHDL Learning (1)Sequential Statement Examples (1) IF-THEN-ELSE For example, a 4 to 1 mulitplexer could be described as follows: mux4_1: PROCESS (d0, d1, d2, d3, BEGIN IF A = “00” THEN x ELSIF A = “01” THEN x ELSIF A = “10” THEN x ELSE x <= d3 ; END IF; END PROCESS mux4_1 ; A) <= d0 ; <= d1 ; <= d2 ; A 2 d0 d1 d2 d3 mux Anytime you want to use IF-THEN-ELSE, then you MUST use a process, because it is a sequential statement x VHDL Learning How can the order of sequential statements make a difference ? ex1: PROCESS (a, b) BEGIN IF a=‘1’ THEN c<=‘0’; END IF; IF b=‘1’ THEN c<=‘1’; END IF; END PROCESS ex1; ex2: PROCESS (a, b) BEGIN IF b=‘1’ THEN c<=‘1’; END IF; IF a=‘1’ THEN c<=‘0’; END IF; END PROCESS ex2; ----- if a and b are both ‘1’ then b has priority so c <= ‘1’; ----- if a and b are both ‘1’ then a has priority so c <= ‘0’; VHDL Learning (2)Sequential Statement Examples (2) CASE-WHEN Another way to describe the same 4 to 1 mux: mux4_1: PROCESS (d0,d1,d2,d3,A) BEGIN CASE A IS WHEN "00" => WHEN "01" => WHEN "10” => WHEN OTHERS => END CASE; END PROCESS mux4_1; x x x x <= <= <= <= d0; d1; d2; d3; A 2 d0 d1 d2 d3 mux Anytime you want to use CASE-WHEN, then you MUST use a process, because it is a sequential statement x VHDL Learning 5、A Note about Processes Signal Assignment Take a look at the following piece of code. Which circuit do you think will be synthesized ? PROCESS (clock) BEGIN IF rising_edge(clock) THEN b <= a; -- after the rising clock edge, a goes to b c <= b; -- after the rising clock edge, b goes to c END IF; END PROCESS ; a a c OR clock clock b c VHDL Learning Signal Assignment in Processes Inside processes, signals are not updated immediately. Instead, they are scheduled to be updated The signals are not actually updated until the END PROCESS statement is reached Therefore, on the previous slide, two registers will be synthesized (c <= b will be the old b) In some cases, the use of a concurrent statement outside the process will fix the problem, but this is not always possible So how else can we fix this problem ? VHDL Learning 6、Variables When a concurrent signal assignment outside the process cannot be used, the previous problem can be avoided using a variable Variables are like signals, BUT they can only be used inside a PROCESS. They cannot be used to communicate information between processes Variables can be of any valid VHDL data type The value assigned to a variable is available immediately Assignment of variables is done using a colon (:), like this: c := a AND b; VHDL Learning Using Variables vs. Signals Solution using a variable within a process: PROCESS (clock) VARIABLE b : std_logic ; BEGIN IF rising_edge(clock) THEN b := a ; -- this is immediate c <= b ; -- this is scheduled END IF; END PROCESS ; a clock c VHDL Learning 五、Native Operators (IEEE-1076) Logical - defined for type BIT, BIT_VECTOR, BOOLEAN AND, NAND OR, NOR XOR, XNOR NOT Relational - defined for types BIT, BIT_VECTOR, INTEGER = (equal to) /= (not equal to) < (less than) <= (less than or equal to) > (greater than) >= (greater than or equal to) VHDL Learning Native Operators (continued) Arithmetic - defined for type INTEGER + (addition), * (multiplication) - (subtraction) Concatenation - defined for STRING & A STRING is any sequence of characters std_logic_vector is an example of a STRING Note: None of these operators were defined to support std_logic or std_logic_vector types because in IEEE-1076, std_logic did not exist yet. How can we fix this problem ? VHDL Learning 2、Overloaded Operators In VHDL, any native operator can be overloaded (means re-defined) to accept any other VHDL type. This is very useful. For example: SIGNAL counter: std_logic_vector(15 DOWNTO 0); counter <= counter + 3; -the native '+' operator supports integers only, but -we can overload it to accept std_logic_vectors also The std_arith package from Cypress defines overloaded logical operators (AND, OR, NOT, etc.,) for the std_logic and std_logic_vector types To get the compiler to recognize std_logic and to overload the operators you need to add 4 lines to the start your VHDL file: LIBRARY ieee; USE ieee.std_logic_1164.all; LIBRARY cypress; USE cypress.std_arith.all; -- add the std_logic type -- add overloaded operators VHDL Learning Exercise #2: Architecture Declaration of a Comparator The entity declaration is as follows: a(0 TO 3) LIBRARY ieee; USE ieee.std_logic_1164.ALL; b(0 TO 3) ENTITY compare IS PORT ( a, b: IN std_logic_vector(0 TO 3); aeqb: OUT std_logic); END compare; Write an architecture that causes aeqb to be asserted high only when a is equal to b Multiple solutions exist. Look back at the 4-1 mux examples aeqb VHDL Learning Ex2 Solution: 3 possible solutions Concurrent statement solution using a conditional assignment: ARCHITECTURE archcompare OF compare IS BEGIN aeqb <= '1' WHEN a = b ELSE '0'; END archcompare; Concurrent statement solution using boolean equations: ARCHITECTURE archcompare OF compare IS BEGIN aeqb <= NOT( (a(0) XOR b(0)) OR (a(1) XOR b(1)) OR (a(2) XOR b(2)) OR (a(3) XOR b(3))); END archcompare; VHDL Learning 3 possible solutions (contd.) Solution using a process with sequential statements: ARCHITECTURE archcompare OF compare IS BEGIN comp: PROCESS (a, b) BEGIN IF a = b THEN aeqb <= '1'; a(0 TO 3) ELSE b(0 TO 3) aeqb <= '0'; END IF; END PROCESS comp; END archcompare; aeqb VHDL Learning 3、Aggregates and Subscripts The aggregate assignment joins signals together Good for creating a bus from several single bits Concatenation operator can be used as well Same number of array elements on both sides tmp <= (a,b,c,d); tmp <= a & b & c & d; -- called an aggregate -- concatenation operator Signals can be extracted from larger vectors Good for grouping outputs as an “alias” Sizes on both sides must match rw <= ctrl(0); ce <= ctrl(1); oe <= ctrl(2); highcount <= count(7 DOWNTO 4); VHDL Learning 4、七段显示译码器设计 LIBRARY Ieee; USE Ieee.std_logic_1164.ALL; --程序中用到的函数库 Entity decoder_7seg is port ( indata :in std_logic_vector(3 downto 0); ena :in std_logic; --bit disp :out std_logic_vector(6 downto 0)); --bit_vector end decoder_7seg; architecture a of decoder_7seg is begin process(indata, ena) begin --如果不要use语句,将std_logic_...改成bit,就可以了 续前 if ena='1' then case indata is -- abcdefg when "0000"=>disp<="1111110"; when "0001"=>disp<="0110000"; when "0010"=>disp<="1101101"; when "0011"=>disp<="1111001"; when "0100"=>disp<="0110011"; when "0101"=>disp<="1011011"; when "0110"=>disp<="1011111"; when "0111"=>disp<="1110000"; when "1000"=>disp<="1111111"; when "1001"=>disp<="1111011"; when others=>disp<= "1110110"; end case; else disp<="1111110"; end if; end process; end a; VHDL Learning 5、八位加法器设计-并行语句实现 VHDL Learning LIBRARY ieee; ENTITY adder_8bits IS PORT (op1, op2 :in integer range 0 to 255); c :out bit; sum END adder_8bits; :out integer); sum :buffer integer ARCHITECTURE a1 OF adder_8bits IS BEGIN --不行的,因为sum定义为out,不能读取其数据 sum <= op1 + op2; c <= '1' when sum>=255 else '0'; END a1; --integer range 0 to 255就规定了数据宽度为8位 VHDL Learning 八位加法器仿真图 八位加法器设计-顺序语句实现 VHDL Learning LIBRARY ieee; ENTITY adder_8bits IS PORT (op1, op2 c sum END adder_8bits; :in integer range 0 to 255; :out bit; :out integer); ARCHITECTURE a2 OF adder_8bits IS BEGIN process(op1,op2) variable num :integer; begin num :=op1 + op2; if num >= 255 then num :=num - 255; c<='1';else c<='0'; end if; sum <= num; end process; --用variable变量就没有其它限制了 END a2; 六、Describing Registers using VHDL VHDL Learning Write a process that is sensitive to a clock edge Example: a D-type flip-flop ENTITY registered IS PORT ( d, clk: IN std_logic; q: OUT std_logic); END registered; ARCHITECTURE archregistered OF registered IS BEGIN flipflop: PROCESS (clk) BEGIN IF rising_edge(clk) THEN q <= d; END IF; END PROCESS flipflop; END archregistered; VHDL Learning Describing Registers using Behavioral VHDL The synthesis compiler knows that a register is to be created for the signal q because: The clock (clk) is in the sensitivity list The construct rising_edge(clk), appears in the process There is no “else” in the “if-then” statement. This implies that if the rising_edge(clk) condition is not true, then q will hold its current value (this is referred to as implicit memory) D触发器VHDL代码-边沿触发器2 ENTITY regdff IS PORT( d clk q END regdff; VHDL Learning : IN BIT; : IN BIT; : OUT BIT); ARCHITECTURE a OF regdff IS BEGIN PROCESS (clk) --敏感信号表 BEGIN IF (clk'EVENT AND clk = '1') THEN --或仅仅clk = '1' q <= d; END IF; END PROCESS; END a; D触发器VHDL代码-边沿触发器3 ENTITY regdff IS PORT( d clk q END regdff; VHDL Learning : IN BIT; : IN BIT; : OUT BIT); ARCHITECTURE a OF regdff IS BEGIN PROCESS --有WAIT语句,可以没有敏感信号表 BEGIN WAIT UNTIL (clk'EVENT AND clk = '1'); q <= d; END PROCESS; END a; clk='1' AND clk'last_value='0' VHDL Learning D触发器VHDL代码-电平触发器 process(clk, d) begin if clk= ’1’ then q<=d; end if; end process; --敏感信号表中有D输入变量 --电平触发型寄存器 有clk和d俩个敏感信号,也就是说当clk变化的时候,即clk上升沿的情况下将当 前的d送入q;而当d变化的时候,启动process,此时clk=‘1’作为一个条件,满足 这个条件则把d送入q,否则跳出process保持原值,综合起来看clk='1'是作为一 个条件,当clk='1'时,也就是当clk为高电平的时候将d送入q,就产生了电平触发 VHDL Learning 2、Implicit memory Remember that inside a process assignments do not occur immediately. Each signal has a current value and may be scheduled for a future value At the end of the process, if a signal has not been assigned to a new value, then a latch will be synthesized to hold the current value Advantages: Helps us to create synchronous flip flops Disadvantages: Can generate unwanted latches in combinatorial logic designs VHDL Learning Implicit memory: Example of incomplete specification ARCHITECTURE archincomplete OF incomplete IS a BEGIN im_mem: PROCESS (a,b) c BEGIN IF a = '1' THEN c <= b; END IF; b END PROCESS im_mem; END archincomplete; Note: the incomplete specification of the IF...THEN... statement causes a latch to be synthesized to hold the previous state of ‘c’ when a = ‘0’ VHDL Learning Implicit memory: Example of complete specification ARCHITECTURE archcomplete OF complete IS BEGIN no_mem: PROCESS (a, b) BEGIN IF a = '1' THEN c <= b; ELSE c <= '0'; END IF; END PROCESS no_mem; END archcomplete; a b The conditional statement is now fully specified, and this causes the process to synthesize to a single gate. There is no implicit memory (latch) synthesized c VHDL Learning The Rules to Avoid Implicit Memory To avoid the generation of unexpected latches Always terminate an IF...THEN... statement with an ELSE clause Cover all alternatives in a CASE statement • Define every alternative individually, or • Terminate the CASE statement with a WHEN OTHERS... clause. For example: CASE select IS WHEN WHEN WHEN WHEN END CASE; "100" "010" "001" OTHERS => => => => key key key key <= <= <= <= first; second; third; none; VHDL Learning 3、A Registered Process (Template #1) A 4-bit counter with synchronous reset LIBRARY cypress; USE cypress.std_arith.ALL; -- overload the + operator upcount: PROCESS (clk) BEGIN IF rising_edge(clk) THEN IF reset = '1' THEN -- synchronous reset count <= "0000"; -- or use x"0" instead ELSE count <= count + 1; END IF; --此处,count定义为buffer或inout类型 END IF; END PROCESS upcount; 否则会出错! This process is only sensitive to changes in “clk”. i.e. it will become active only when the clock transitions VHDL Learning A Registered Process (Template #2) A 4-bit counter with asynchronous reset LIBRARY cypress; USE cypress.std_arith.ALL; upcount: PROCESS (clk, rst) BEGIN IF rst = '1' THEN count <= x"0"; ELSIF rising_edge(clk) THEN count <= count + 1; END IF; END PROCESS upcount; This process is sensitive to changes in both clk and rst. i.e. it will become active during clock or reset transitions. VHDL Learning A Registered Process (Template #3) A 4-bit loadable counter with asynchronous reset LIBRARY cypress; ... USE cypress.std_arith.ALL; upcount: PROCESS (clk, rst) BEGIN IF rst = '1' THEN count <= x"0" ; ELSIF rising_edge(clk) THEN IF load = '1' THEN count <= data; ELSE count <= count + 1; END IF; END IF; END PROCESS upcount; 任意进制计数器 with asynchronous reset VHDL Learning library ieee; ENTITY mycounter is port( clk, clear:in bit; c: out bit; qc: out integer range 0 to 15); constant modulus: integer :=10; --设定计数器模数 end mycounter; architecture a of mycounter is begin PROCESS (clk, clear) VARIABLE cnt : integer range 0 to 16; BEGIN IF (clear=‘0’) THEN cnt:= 0; c<=‘0’; --异步清零 ELSIF (clk'EVENT AND clk = '1') THEN cnt:=cnt+1; if cnt=modulus-1 then c<=‘1’; end if; --进位信号赋值 if cnt=modulus then cnt :=0; c<='0'; end if; END IF; qc<=cnt; --赋值到输出 END PROCESS; end a; VHDL Learning Exercise #4 Making use of the previous examples, write ONE entity/architecture pair for the following design: DATA LD 4 COUNTER DIN LD COUNT Q 4 ENC CLOCK COMPARATOR P RST RESET (sync) PEQQ Q REGISTER DIN ENR ENR Q 4 Exercise #4: Solution VHDL Learning LIBRARY ieee; USE ieee.std_logic_1164.ALL; LIBRARY cypress; USE cypress.std_arith.ALL; -- overload ‘+’ for counter ENTITY ex4 clock, data: count: END ex4; IS PORT ( reset, ld, enr: IN std_logic; IN std_logic_vector (3 DOWNTO 0); BUFFER std_logic_vector (3 DOWNTO 0)); ARCHITECTURE archex4 OF ex4 IS SIGNAL peqq: std_logic; SIGNAL regout: std_logic_vector (3 DOWNTO 0); BEGIN reg: PROCESS (clock) BEGIN IF rising_edge(clock) THEN IF enr=‘1’ THEN regout <= data; END IF; END IF; END PROCESS reg; VHDL Learning Exercise #4: Solution (contd.) cntr: PROCESS (clock) BEGIN IF rising_edge(clock) THEN IF reset = '1' THEN count <= "0000"; ELSIF ld = '1' THEN count <= data; ELSIF (peqq = ’0') THEN count <= count + 1; END IF; END IF; END PROCESS cntr; peqq <= '1' WHEN (regout = count) ELSE '0'; END archex4; VHDL Learning 七、State Machines Many implementations are possible, including: Automatic State Assignment • the compiler chooses the state encoding • outputs must be decoded from the state registers – can be a combinatorial decode – can be a registered decode Specific State Assignment • you choose the state encoding – outputs may be encoded inside the state registers 串行数据检测器-variable实现 library ieee; use ieee.std_logic_1164.all; VHDL Learning entity stmch1 is port(clk, x, rst: in std_logic; y: out std_logic); end stmch1; architecture behave of stmch1 is begin --自定义一种variable数据类型:3个状态的枚举类型 process (clk, rst) type state_values is (s0, s1, s2); variable state, next_state: state_values; begin if rst = ‘1’ then state := s0; y <=‘0’; --异步清零 elsif rising_edge(clk) then --上升沿触发 case state is --状态变化规律 when s0 => if x = '1' then next_state := s1; y <='0'; else next_state := s0; y <='0'; end if; when s1 => if x = '1' then next_state := s2; y <='0'; else next_state := s0; y <='0'; end if; when s2 => if x = '1' then next_state := s2; y <='1'; else next_state := s0; y <='0'; end if; when others => next_state := s0; y <='0'; end case; state := next_state; --状态转换 end if; end process; 没有明确状态编码! end behave; VHDL Learning 串行数据检测器仿真图 library ieee; use ieee.std_logic_1164.all; 串行数据检测器-signal实现 VHDL Learning entity stmch2 is port(clk, x, rst: in std_logic; y: out std_logic); end stmch2; --自定义一种signal数据类型:3个状态的枚举类型 architecture behave of stmch2 is type state_values is (s0, s1, s2); signal state : state_values; begin process (clk, rst) begin if rst = '1' then state <= s0; y <='0'; elsif rising_edge(clk) then case state is when s0 => if x = '1' then state <= s1; y <='0'; else state <= s0; y <='0'; end if; when s1 => if x = '1' then state <= s2; y <='0'; else state <= s0; y <='0'; end if; when s2 => if x = '1' then state <= s2; y <='1'; else state <= s0; y <='0'; end if; when others => state <= s0; y <='0'; end case; end if; end process; end behave; library ieee; 串行数据检测器-signal实现进程间通信 VHDL Learning entity stmch5 is port(clk, x, rst: in bit; y: out bit; st:out bit_vector(1 downto 0)); end stmch5; architecture behave5 of stmch5 is type state_values is (s0, s1, s2); signal state : state_values; --定义signal类型枚举变量 begin pro1:process (clk, rst) begin ----进程1,时序逻辑 if rst = '1' then state <= s0; y <='0'; elsif clk'event and clk='1' then case state is when s0 => if x = '1' then state <= s1; y <='0'; else state <= s0; y <='0'; end if; when s1 => if x = '1' then state <= s2; y <='0'; else state <= s0; y <='0'; end if; when s2 => if x = '1' then state <= s2; y <='1'; else state <= s0; y <='0'; end if; when others => state <= s0; y <='0'; end case; end if; end process; -------进程2,将时序状态译码输出 pro2:process(state) begin case state is when s0 => st <="00"; when s1 => st <="01"; when s2 => st <="11"; when others => st <="10"; end case; end process; end behave5; VHDL Learning Example: A Traffic Light Controller Let’s take a look at an example state machine and see how to describe it using the 3 types of implementations: TIMER2 TIMER3 RESET (asynchronous) TIMER1 TIMER2 RED GREEN R='1' G='1' YELLOW TIMER1 TIMER3 Y='1' VHDL Learning Example: The Entity Declaration The entity declaration remains exactly the same for each implementation. For example: LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY state_machine IS PORT ( clock, reset: timer1, timer2, timer3: r, y, g: END state_machine; IN std_logic; IN std_logic; OUT std_logic); VHDL Learning Example: Solution 1 Combinatorial outputs decoded from the state registers ARCHITECTURE arch_1 OF state_machine IS TYPE traffic_states IS (red, yellow, green); -- enumerated type SIGNAL sm: traffic_states; BEGIN fsm: PROCESS (clock, reset) -- the process describes the BEGIN -- state machine only IF reset = '1' THEN sm <= red; ELSIF rising_edge(clock) THEN CASE sm IS WHEN red => IF timer1=‘1’ THEN sm <= green; END IF; WHEN green => IF timer2=’1' THEN sm <= yellow; END IF; VHDL Learning Example: Solution 1 (contd.) WHEN yellow => IF timer3=’1' THEN sm <= red; END IF; WHEN others => sm <= red; END CASE; END IF; END PROCESS fsm; -- the outputs are decoded from the state machine -- registers using combinatorial logic r <= '1' WHEN (sm = red) ELSE '0'; g <= '1' WHEN (sm = green) ELSE '0'; y <= '1' WHEN (sm = yellow) ELSE '0'; END arch_1; VHDL Learning (1) Automatic State Assignment: Combinatorial Decode of Outputs Outputs decoded from state bits COMBINATORIALLY combinatorial output logic is in series with state registers outputs are a function of the present state only time from clock to output (tco) is long Present State Inputs Next State Logic Next State Output Logic State Registers tco Outputs VHDL Learning Example: Solution 2 Registered outputs decoded from the state registers ARCHITECTURE arch_2 OF state_machine IS TYPE traffic_states IS (red, yellow, green); SIGNAL sm: traffic_states; BEGIN fsm: PROCESS (clock, reset) -- the process describes the BEGIN -- state machine AND the outputs IF reset = '1' THEN sm <= red; r<=‘1’; g<=‘0’; y<=‘0’; ELSIF rising_edge(clock) THEN CASE sm IS WHEN red => IF timer1=‘1’ THEN sm <= green; r<=‘0’; g<=‘1’; y=‘0’; ELSE sm <= red; r<=‘1’; g<=‘0’; y=‘0’; END IF; VHDL Learning Example: Solution 2 (contd.) WHEN green => IF timer2=’1' THEN sm <= yellow; r<=‘0’; g<=‘0’; y<=‘1’; ELSE sm <= green; r<=‘0’; g<=‘1’; y<=‘0’; END IF; WHEN yellow => IF timer3=’1' THEN sm <= red; r<=‘1’; g<=‘0’; y<=‘0’; ELSE sm <= yellow; r<=‘0’; g<=‘0’; y<=‘1’; END IF; WHEN others => sm <= red; END CASE; END IF; END PROCESS fsm; END arch_2; VHDL Learning (2) Automatic State Assignment: Registered Decode of Outputs Outputs decoded from state bits using REGISTERS registered output logic is in parallel with state registers outputs are a function of the previous state and the inputs tco is shorter, but you need more registers Inputs Next State Logic State Registers Output Logic Output Registers tco Present State Outputs VHDL Learning Example: Solution 3 Outputs encoded inside the state registers ARCHITECTURE arch_3 OF state_machine IS SIGNAL CONSTANT CONSTANT CONSTANT sm: red: green: yellow: std_logic_vector(2 std_logic_vector(2 std_logic_vector(2 std_logic_vector(2 DOWNTO DOWNTO DOWNTO DOWNTO 0) 0) 0) 0) ; := ”100" ; := "010" ; := "001" ; BEGIN fsm: PROCESS (clock, reset) -- the process describes the BEGIN -- state machine only IF reset = '1' THEN sm <= red; ELSIF rising_edge(clock) THEN CASE sm IS WHEN red => IF timer1=‘1’ THEN sm <= green; ELSE sm <= red; END IF; VHDL Learning Example: Solution 3 (contd.) WHEN green => IF timer2=’1' THEN sm <= yellow; ELSE sm <= green; END IF; WHEN yellow => IF timer3=’1' THEN sm <= red; ELSE sm <= yellow; END IF; WHEN others => sm <= red; END CASE; END IF; END PROCESS fsm; r <= sm(2); g <= sm(1); y <= sm(0); END arch_3; -- the outputs are just taken from -- the state machine registers -- (no decode logic required) VHDL Learning (3) Specific State Assignment We encoded the outputs within the state registers State r g y State Encoding red 1 0 0 100 green 0 1 0 010 yellow 0 0 1 001 Note: All bits of the state encoding were used as outputs Inputs Logic State Registers Outputs VHDL Learning StateMachines: Summary Outputs decoded from the state machine registers • simplies the design process • using enumerated types allows automatic state assignment during compilation • but, performance (speed) may not be optimal Outputs encoded within the state machine registers • manual state assignment using constants • the state registers and the outputs are merged • reduces the number of registers • but, may require more complex logic [题6.30]用常用的时序逻辑电路设计,要求可以自启动。 VHDL Learning CLK 红 黄 绿 0 0 0 0 1 1 0 0 2 0 1 0 3 0 0 1 4 1 1 1 5 0 0 1 6 0 1 0 7 1 0 0 8 0 0 0 计数器仅仅起提供合适的时序的作用,计数作用不明显了。 library ieee; entity statee is port(clk :in bit; red, yellow, green: out bit); end entity statee; VHDL Learning architecture behave of statee is signal q :integer range 0 to 7; begin --定义了时序 cnt: process(clk) variable cnt: integer range 0 to 7; begin if clk'event and clk='1' then if cnt < 7 then cnt:=cnt+1; else cnt:=0; end if;end if; q <= cnt; end process cnt; --定义了状态对应的输出 com: process(q) begin case q is when 0 => red <='0'; yellow <= '0'; green <= '0'; when 1 => red <='1'; yellow <= '0'; green <= '0'; when 2 => red <='0'; yellow <= '1'; green <= '0'; when 3 => red <='0'; yellow <= '0'; green <= '1'; when 4 => red <='1'; yellow <= '1'; green <= '1'; when 5 => red <='0'; yellow <= '0'; green <= '1'; when 6 => red <='0'; yellow <= '1'; green <= '0'; when 7 => red <='1'; yellow <= '0'; green <= '0'; end case; end process com; end architecture behave; 结果对比 VHDL Learning CLK 红 黄 绿 0 0 0 0 1 1 0 0 2 0 1 0 3 0 0 1 4 1 1 1 5 0 0 1 6 0 1 0 7 1 0 0 8 0 0 0 VHDL Learning 八、Hierarchical (Modular) Designs A hierarchical design is one which is broken down into many levels, with a top level design bringing all the lower-level components together This allows very complex designs to be divided down into smaller, more easily managed modules In the past, this was the major advantage of schematic capture tools But, VHDL also supports hierarchical designs !! VHDL Learning Hierarchical Design Methodology Advantages: Components (VHDL models) can be created, tested and stored for later use (re-usable code) Allows the re-use of common building blocks Allows you to purchase 3rd Party off-the-shelf modules (e.g. UART, PCIbus Interface etc) Makes the design more readable and easier to understand Complex design tasks can be split across many designers in a team VHDL Learning VHDL Hierarchy Decomposition In VHDL, hierarchy is composed of: COMPONENTs • entity/architecture pairs which can be instantiated (placed) within other designs PACKAGEs • a collection of one or more COMPONENTs and other declarations LIBRARIES • a collection of COMPILED design units • e.g. packages, components, entity/architecture pairs etc. VHDL Learning Hierarchy: Schematic Capture vs. VHDL c b a c r t b sel sel • • mux2to1 p q a schematic entity/architecture s toplevel mux2to1 • • mux2to1 top level schematic top level entity/architecture a • • c b sel • • symbol component library package VHDL Learning Hierarchy Management Libraries are used to store re-usable components, type definitions, overloaded operators etc. You add the ‘LIBRARY’ and ‘USE’ clauses to your code to get access to them Your Design (VHDL) LIBRARY ieee; USE ieee.std_logic_1164.. LIBRARY cypress; USE cypress.std_arith.all Library (Compiled) Packages (VHDL) ieee std_logic_1164 Library (Compiled) Packages (VHDL) cypress std_arith Others (VHDL) std_logic type definitions Others (VHDL) overloaded operators VHDL Learning Package and Component Declarations When you have created a working entity/architecture pair, you need to add a component declaration to make it a re-usable COMPONENT COMPONENTS need to be stored in PACKAGES, so you need to write a package declaration to store all your components When you compile your package with no errors, the components will be stored in the WORK library WORK is the default library where everything YOU compile gets stored. Because it is the default library, you do NOT need to add: LIBRARY WORK; -- not required VHDL Learning Package and Component Declarations: An Example LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY mux2to1 IS PORT ( a, b, sel: IN std_logic; c: OUT std_logic); END mux2to1; Entity/Architecture File (VHDL) ARCHITECTURE archmux2to1 OF mux2to1 IS BEGIN c <= (a AND NOT sel) OR (b AND sel); END archmux2to1; LIBRARY ieee; USE ieee.std_logic_1164.ALL; PACKAGE mymuxpkg IS COMPONENT mux2to1 PORT ( a, b, sel: IN std_logic; c: OUT std_logic); END COMPONENT; END mymuxpkg; Package and Component Declaration File (VHDL) VHDL Learning Top Level Sheet: Example Signals are connected via a PORT MAP that associates signals with the component’s I/O The port map describes how to “wire-up” the component LIBRARY ieee; -- get access to the ieee library USE ieee.std_logic_1164.ALL; -- get access to std_logic_1164 package ENTITY toplevel IS PORT (s: IN std_logic; p, q, r: IN std_logic_vector(2 DOWNTO 0); t: OUT std_logic_vector(2 DOWNTO 0)); END toplevel; USE WORK.mymuxpkg.ALL; -- get access to the mymuxpkg package ARCHITECTURE archtoplevel OF toplevel IS SIGNAL i: std_logic_vector(2 DOWNTO 0); BEGIN m0: mux2to1 PORT MAP (a=>i(2), b=>r(0), sel=>s, c=>t(0)); m1: mux2to1 PORT MAP (c=>t(1), b=>r(1), a=>i(1), sel=>s); i <= p AND NOT q; END archtoplevel; VHDL Learning Exercise #6 The same design from ex4. This time, we’ll use a separate entity/architecture for each block and use VHDL hierarchy DATA LOAD 4 COUNTER DIN COUNT LD Q 4 ENC CLOCK COMPARATOR P RST RESET (sync) PEQQ Q REGISTER DIN ENR ENR Q 4 VHDL Learning Exercise 6 Solution: package.vhd LIBRARY ieee; USE ieee.std_logic_1164.ALL; PACKAGE ex6_pkg IS COMPONENT comp4 PORT ( p, q : IN std_logic_vector (3 DOWNTO 0); peqq : OUT std_logic); END COMPONENT; COMPONENT reg4 PORT ( clk, enr : IN std_logic; din : IN std_logic_vector(3 DOWNTO 0); q : OUT std_logic_vector(3 DOWNTO 0)); END COMPONENT; VHDL Learning Exercise 6 Solution package.vhd (cont) COMPONENT count4 PORT( clk, enc, ld, rst : IN std_logic; din : IN std_logic_vector(3 downto 0); q : BUFFER std_logic_vector(3 downto 0)); END COMPONENT; END ex6_pkg; VHDL Learning Exercise 6 Solution Top Level File: ex6.vhd LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY ex6 IS PORT ( load, clock, reset, enr : IN std_logic; data : IN std_logic_vector(3 DOWNTO 0); count : BUFFER std_logic_vector(3 DOWNTO 0)); END ex6; USE work.ex6_pkg.ALL; ARCHITECTURE ex6_arch OF ex6 IS -- get access to your components SIGNAL regout : std_logic_vector(3 DOWNTO 0); SIGNAL peqq : std_logic; SIGNAL not_peqq : std_logic; -- internal bus -- internal net -- internal net VHDL Learning Exercise 6 Solution Top Level File: ex6.vhd (cont.) BEGIN U1: count4 PORT MAP (din=>data, ld=>load, enc=>not_peqq, clk=>clock, rst=>reset, q=>count); U2: reg4 PORT MAP (din=>data, enr=>enr, clk=>clock, q=>regout); U3: comp4 PORT MAP (p=>count, q=>regout, peqq=>peqq); not_peqq <= NOT(peqq); END ex6_arch; -- create the inverter 层次设计的例子 ------my hierarchy example 2008.4.28 library ieee; entity ab is port( in1, in2: in bit; y: out bit; re:out integer range 0 to 16); end entity ab; architecture myr of ab is component mycounter -------声明元件 port(clk, clear:in bit; c: out bit; qc: out integer range 0 to 16); end component; begin ad1: mycounter PORT MAP (clk=>in1, clear=>in2, c=>y, qc=>re); end myr; -----------------------my counter component--------定义元件,位置前后都可以 library ieee; ENTITY mycounter is port( clk, clear:in bit; c: out bit; qc: out integer range 0 to 16); constant modulus: integer :=10; end mycounter; architecture a of mycounter is begin PROCESS (clk, clear) VARIABLE cnt : integer range 0 to 16; BEGIN IF (clear='0') THEN cnt:= 0;c<='0'; ELSIF (clk'EVENT AND clk = '1') THEN cnt:=cnt+1; if cnt=modulus-1 then c<='1'; end if; if cnt=modulus then cnt:=0; c<='0'; end if; END IF; qc<=cnt; END PROCESS; end a; VHDL Learning VHDL Learning Miscellaneous Topics: Tri-State Logic ENTITY test_three IS PORT( oe : IN std_logic; data : OUT std_logic_vector(0 to 7)); END test_three; ARCHITECTURE archtest_three OF test_three IS BEGIN PROCESS (oe) BEGIN IF (oe='1') THEN data <= "01100100"; ELSE data <= "ZZZZZZZZ"; -- assigning a value of ‘Z’ END IF; -- tri-states an output END PROCESS; END archtest_three; VHDL Learning Miscellaneous Topics: Bi-directional pins ENTITY ldcnt IS PORT ( clk, ld, oe: IN std_logic; count: INOUT std_logic_vector(7 DOWNTO 0)); END ldcnt; ARCHITECTURE archldcnt OF ldcnt IS SIGNAL int_count: std_logic_vector(7 DOWNTO 0); BEGIN -- first create an internal signal cnt: PROCESS (clk) BEGIN IF rising_edge(clk) THEN IF ld='1' THEN int_count <= count; -- count as "IN" ELSE int_count <= int_count + 1; END IF; END IF; END PROCESS cnt ; outen: PROCESS (oe, int_count) BEGIN IF oe = '1' THEN count <= int_count ; -- count as "OUT" ELSE count <= (OTHERS => 'Z') ; -- count as "OUT" END IF ; -- equivalent to count <= "ZZZZZZZZ" END PROCESS outen; END archldcnt; VHDL Learning Miscellaneous Topics: Assigning a Don’t Care To assign don’t cares in VHDL, use a ‘-’. Note that ‘X’ means unknown in VHDL and cannot be used for synthesis Warp uses explicit "don’t care" conditions to produce optimal logic equations IF (a = '1') AND (b = '1') THEN y <= c; ELSE y <= '-'; END IF; Would be reduced to the equation y <= c VHDL Learning The pin_numbers attribute Gets attached to the entity Used to map the external signals of an entity to the pins on the target device Allows the back-annotation of pin placements after synthesis Must be placed inside the entity ENTITY counter IS PORT ( clock, reset: IN std_logic; count: OUT std_logic_vector(3 DOWNTO 0) ); ATTRIBUTE pin_numbers OF counter:ENTITY IS "clock:13 reset:2" & " count(3):3 count(2):4 count(1):5 count(0):6"; END counter;