UNIVERSITY OF GLASGOW Degrees of MEng, BEng, BSc and MSc in Engineering DIGITAL ELECTRONICS 2 (ENG2020) Thursday 6 December 2018 13:00-15:00 Attempt ALL questions. Total 100 marks The numbers in square brackets in the right-hand margin indicate the marks allotted to the part of the question against which the mark is shown. These marks are for guidance only. A Simple Guide to VHDL and some device data sheets are appended to this paper and may be used in any question. Page 1 of 35 Continue Overleaf Section A Total marks for this section is 30, each question is worth 5 Q1 Figure Q1 shows the block diagram for a module ‘X’. Write the entity statement in VHDL which would define the interface for X. All signals are digital connections. Z is a three line bus. [5] Module X A B C clock Z 3 Figure Q1. Q2 Describe the operation of the TC (sometimes called RCO) pin on the 74HC163 counter chip and give an example of its use. [5] Q3 Sketch the combinational logic circuit described by this VHDL entity. [5] entity Rip is port (Ent : in std_logic; Q : in std_logic_vector(3 down to 0); RCO : out std_logic); end Rip; architecture struc of Rip is signal MaxCnt : std_logic; begin MaxCnt <= Q(1) and Q(2) and Q(3) and Q(4); RCO <= MaxCnt and EnT; end struc; Q4 Figure Q4 depicts a generalised finite state machine. Copy and complete this figure by labeling all the buses, and functional blocks. [5] OUTPUTS inputs Figure Q4. Page 2 of 35 Continue Overleaf Q5 Figure Q5 shows a logic circuit. Write a fragment of VHDL (entity, architecture and signal statements not required) to implement this logic. [5] X Y Z Q Figure Q5. Q6 Write a fragment of VHDL (entity definitions and architecture statements are not required) which resets a 3 bit count to 0 asynchronously if input Rst goes high. If Rst is not active (low) the count increments on the rising edge of a clock pulse. On reaching the count “111” the counter rolls over in the usual way back to “000” and continues. You can assume that Count is defined as: [5] signal Count : unsigned(2 downto 0); Page 3 of 35 Continue Overleaf Section B Total marks for this section is 30, each question is worth 10 Q7 The VHDL in figure Q7 describes a system which takes in a 5 bit number and outputs a modulated value. Draw the block diagram for the circuit, labelling all the inputs, outputs and components. [8] Given the names of the components, can you form a description of what function this circuit is likely to be implementing? [2] library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Modulator5bit is port(Clock, Rst : std_logic; PWM_value : in std_logic_vector(4 downto 0); COunt5out : out std_logic_vector(4 downto 0); PWM_drive : out std_logic); end Modulator5bit; Architecture behaviour of Modulator5bit is component comparator5bit is port(A,B : in std_logic_vector(4 downto 0); AgrB : out std_logic); end component; component count5bit is port(clock,rst : in std_logic; count : out std_logic_vector(4 downto 0)); end component; signal count5 : std_logic_vector(4 downto 0); begin compare: comparator5bit port map(PWM_value,Count5,PWM_Drive); counter: count5bit port map(clock,rst,count5); count5out <= count5; end Behaviour; Figure Q7. Page 4 of 35 Continue Overleaf Q8 Table Q8 is a transition table for a finite state machine which has one input, named U. Draw the fully labelled state diagram. [10] Present Next state input state number U 0 0 1 0 1 0 1 0 2 1 1 1 2 0 3 2 1 2 3 0 0 3 1 3 Table Q8. Q9 A finite state machine is defined by the state diagram in figure Q9a. The clock input is called ‘clk’ and there is an input ‘H’. If it starts in state S0 and receives the sequence of inputs as shown in figure Q9b, draw a time trace of the outputs which the machine will produce. Outputs are [X,Y,Z] and the machine is positive edge triggered. [10] S0 [101] H= 0 S2 [101] S1 [100] S4 [010] H = 1 S3 [001] Figure Q9a. Clk H Figure Q9b. Page 5 of 35 Continue Overleaf Section C Total marks for this section is 40, each question is worth 20 Q10 Figure Q10 shows the outline for a circuit which implements a 16 bit pseudo random binary shift register. It is to be used to create a random pattern of lights on 16 LEDs connected to the output bus LED_Out. This bus is made up of the output of two 8 bit shift registers. The registers are connected in series to create a full 16 bit unit. Feedback logic sends data back to the serial input. 8 bit shift register Serial in Clock load 1 2 3 4 5 6 7 8 Ld Clk 8 bit shift register Serial in Clock load 1 2 3 4 5 6 7 8 LED_Out(1-16) Figure Q10. You are to outline VHDL for an architecture which could implement this logic and write the appropriate entity statement. [20] You can assume an 8 bit shift register function is available whose entity statement is: entity Shift8bit is port(Clock, Load, Serial_in : in std_logic; shiftQ8 : out std_logic_vector(1 to 8)); end shift8bit; Q11 A signal ‘Q’ has to be derived from a master clock signal. The frequency of Q has to be six times lower than the clock. Q does not need to be a symmetrical square wave. Design a circuit to accomplish this. The circuit should be capable of being implemented using 74 series logic devices and the devices need to be identified. [20] Page 6 of 35 Continue Overleaf Digital Electronics 2 Abbreviated data sheets For exam use only. The data sheets in this section are a selection from 74 series logic chips from both Texas and Philips. Contents: Function Chip 74xx NAND, 2 input 00 NOR, 2 input 02 NOT 04 Binary counter, 4 bit 163 Shift register, bidirectional, 4 bit 194 Page 7 of 35 Continue Overleaf Page 8 of 35 Continue Overleaf Page 9 of 35 Continue Overleaf Page 10 of 35 Continue Overleaf Page 11 of 35 Continue Overleaf Page 12 of 35 Continue Overleaf Page 13 of 35 Continue Overleaf Page 14 of 35 Continue Overleaf Department of Electronic and Electrical Engineering The University of Glasgow Digital Electronics 2 (Very) Simple Guide to VHDL Introduction VHDL (VHSIC Hardware Description Language) is a comprehensive language for describing and defining logical circuitry. Here is a VERY simple guide to the most basic of VHDL constructs. No attempt is made here to be elegant or describe all possibilities in detail, the minimum to get by is all there is! VHDL is written as a series of modules, each if which is like a circuit block. Often in schematic diagrams such functions would be shown as simple rectangles with input and output connections as named pins, or connectors. This fundamental building block of VHDL is called an entity. The entity defines the connections in and out of the block, within the entity the internal workings of the function are described and defined. Entities VHDL entities are the ‘chunks’ from which bigger circuits can be built. The entity has two parts, the port description and the architecture. Note that the ‘begins’ and ‘ends’ and the structure of the various names and their placement are mandatory. If libraries are referenced, links must also be included. The overall structure is as follows: Library references to libraries being used; Entity A_something is Port ( definitions of the inputs and outputs ); End A_something; Architecture behaviour of A_something is Begin Lines describing what the entity does End behaviour; The port statement defines the ‘connector’ with the outside world, the ins and outs. The architecture describes how the entity implements its function. Here is an example of a simple ‘And’ gate. The code has references to libraries, a basic port with two inputs and one output, and the architecture has one processing statement, the actual AND action. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity simple_gate is port(A,B : in std_logic; Q : out Std_logic); end simple_gate; architecture behaviour of simple_gate is begin Q <= A and B; end behaviour; Page 15 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Libraries The only libraries used in this basic document are shown below. These have to be added before all entities which require it. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; Architectures The architecture holds the actual VHDL which implements the workings of the entity. It is the working section. The architecture body has two segments: - The bit between architecture heading and ‘begin’. - The bit between ‘begin’ and ‘end’. The architecture heading The architecture line has two names, the first is often put in as ‘behaviour’. This name is user defined and comes into play when one entity can have different architectures (– so here we don’t use it and generally leave it as simply ‘behaviour’!). This name has to correspond with the one on the ‘end’ statement. The second name is the name of the entity with which this architecture is associated. The form is therefore: architecture My_behaviour of My_entity is .. heading definitions .. begin .. working statements .. end My_behaviour; Heading statements The heading part contains any definitions which will be used in the body part. These are signals which define internal connections within the architecture and also definitions which describe other entities that this architecture uses. This example shows two internal signals being defined and one other entity ‘snark’ being referenced via a component statement. architecture behaviour of kersplonk is component snark port (A,B : in std_logic; Cout : out std_logic); end component; signal C_Int : unsigned(3 downto 0); signal RCO_int : std_logic; begin Architecture body part The body part contains the working statements. Any named item has to have been previously defined, either as a ‘signal’, a ‘component’, or in the entity’s port definition. Some statements Page 16 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL are compound and complex items in their own right e.g. processes. An example of an architecture body is given below: architecture behaviour of L_dim is begin .. definitions .. Count <= COunt_int; -- direct assignment Mark <= Mark_int; compnt1: inc_dec_counter port map(clock,M_int); -- using a component procs1 : process ) -- using a process (clock,Rst begin .. process statements .. end Process; end behaviour; Ports and Signals A port defines the connectors to an entity. It has to define whether signals are either input or output, and what type they are. The code word signal is for defining connections and values within an entity and thus are used in the architecture heading. Examples: entity counter163 is port(clock,EnT,EnP : in std_logic; D : in std_logic_vector (3 downto 0); Count : out std_logic_vector(3 downto 0); end Counter163; RCO : out Std_logic); architecture behaviour of counter163 is signal Count_Int : unsigned(3 downto 0); signal RCO_int : std_logic; begin .. Lines describing what the entity does .. Signal definitions and types Signals define the nature and type of connections. Essentially they describe wires or busses. They may be between entities or within architectures. Between entities signals must have a direction viz. ‘in’ or ‘out’ (bidirectional signals e.g. busses can use ‘inout’). The actual values that are allowed depend on the libraries in use. The definitions here depend on the IEEE libraries. For ‘std_logic’, the basic logical signal, the values allowed are: U Undefined. X Unknown. 0 Logic Zero. 1 Logic One. Z High Impedance. W Weak Unknown. L Weak Zero. H Weak One. - Don't Care. Page 17 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL The various codes allowed for std_logic clearly model real logic. When they have to be combined, such as in logical expressions, there is a matrix which defines whether say a ‘1’ overcomes an ‘L’ and so on. Single values can be assigned or defined as the value codes e.g. X <= ‘1’ or, IF (Q = ‘Z’). Groupings of logical signals can be made describe busses viz.: Std_logic_vector(X downto Y) a bus of X-Y+1 std_logic lines, with the most significant being the Xth. Std_logic_vector(X to Y) same as above, but most significant line is Y. Literals, are lists of values enclosed between “… ”. They are the way to define values for std_logic_vector: e.g. D <= “0010”; If (X = “01ZZ”) then … Constants can be defined. The example below defines a two bit vector of value 01. Constant S1 : std_logic_vector(1 downto 0) := “01”; Other types of signal can be defined. Another used in this guide is. ‘unsigned’. Unsigned(X downto Y) a collection of signals which communicate an unsigned binary integer of length X-Y+1 bits. Basic arithmetic is allowed between unsigned signals e.g. ‘+’ and ‘-‘; Statements Basic VHDL code is implemented in a series of statements. These generally end with a ‘;’. Some statements are compound, e.g. ‘IF’ clauses and ‘case’ statements. Some can only be used within processes (see later). Statement lines can optionally have an identifier (before a ‘:’). Examples are: Line1 : Q <= X or Y; Count1 : process( ..etc.. Comments can be inserted behind a ‘--‘ e.g. Line1 : Q <= X or Y; -- here is a comment Processing of statements The processing of working statements is not as per normal programming languages. VHDL is intended to simulate the workings of real circuitry. Since real circuits are constantly active, VHDL has also to be reactive to all changes and at all times. Thus, though VHDL may look like familiar sequential programming languages e.g. C++ it does not execute in the same way. It essentially reacts to a series of events. When an event occurs (say an input changing state, or a clock tick) its resulting consequences are dealt with by repeatedly recalculating all the statements in the architecture until any changes settle down to a steady state. The event can be described as being dealt with in ‘zero time’. Once one event has settled, the execution moves on to the next event. In this way the VHDL code can simulate the constantly reactive real Page 18 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL circuit. The net effect is that all statements in an architecture body appear to work in parallel. (Well - nearly all - process statements differ, see later.) Assignment Statements The symbol for assignment is: ‘<=’ Example: X <= Y; This is the most basic statement. The statement X <= Y should be read as ‘X becomes the current value of Y’. The right hand side of the assignment can be a complex thing. It can use operators to combine many signals. The operators need to be interpreted depending on the type of signals in use. Common operators are: ‘+’, ‘-‘ if signals are numeric (e.g. unsigned) AND, OR, NOT, NOR, NAND, XOR if signals are logical. Examples: Q <= (X OR Y) AND (NOT(Z)); Count <= Count + 1; Components Components allow entities defined elsewhere to be invoked locally and used as encapsulated units within an architecture. This is the basic way of implementing circuits using assemblies of modules. The component statement describes the interface of the entity so that the local architecture knows what it links with. The component statement must have the same name and details as the entity to which it refers. Example: If the entity to be used as a component has the port definition: entity test_gate is port(A,B : in std_logic; Q : out std_logic); end test_gate; This entity would be referenced in the architecture using it by the component statement as below where also an example of its being used is included. architecture behaviour of tester is component test_gate port (A,B : in std_logic; Q : out std_logic); end component; signal lcl_A,Lcl_B,Lcl_Q : std_logic; begin g1 : test_gate port map(lcl_A,Lcl_B,Lcl_Q); …… etc … End behaviour; The component is invoked by using its name within the processing statements of the architecture. The ‘port map’ clause makes the link between names in the local architecture and the interface signals of the entity. The port map takes each signal position from left to right and maps it to the signals in the entity’s port definition also from left to right. Page 19 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Processes and statements within processes Within a process, the statements execute in sequential order. Thus, not like statements in the main architecture body. The process itself as a whole however executes in parallel with any other processes and statements in the architecture. Thus a process is like a compound statement. Processes are defined, and lie within, an architecture body. A process is defined by using the process statement viz. process(…sensitivity list…) begin .. end process; statements of the process.. Processes are activated only when an event occurs to any of the signals in their ‘sensitivity list’. Although all signals in the architecture are available for use within a process, only changes to those in the sensitivity list will cause it to execute. Process statements Processes differ from architectures in that their statements run sequentially. Many statements are only valid within a process. Normal assignment e.g. A <= X and Z; is allowed within processes. IF statement, this can only be used within a process. Example if EnP ='1' then else << statements done if test is true >> << statements done if test is false >>> end if; If the result of the test part is true the first group of statements is executed, if the statement is false, the (optional) second group is executed. IF statements can be nested and tests can be compound e.g. if (EnP ='1') and (Rst =’0’) then if x = ’0’ then y <= z or X; else y <= Z and X; end if; end if; The tests here are shown as tests against the std_logic values, of ‘1’ and ‘0’. ‘Else if’ is allowed as : IF … then…elsif …then … else… end if; Case statement, only to be used within a process. Looking at the skeleton below, the statements on the right hand side of the ‘=>’ are executed if the pattern or values on the left hand side match the value of the subject of the case. Nesting is allowed, so the right hand side can be more case or IF statements. In the example ‘count’ is a 4 bit vector. Page 20 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL case Count is when "0000" => XY <= "000"; when "0100" => if z = ’0’ then XY <= "010"; else XY <= "111"; End if; when others => XY <= "000"; end case; The ‘others’ clause is not mandatory, but is generally safer. It must be remembered that ‘1’ and ‘0’ are not the only values for std_logic, the others e.g. ‘Z’ etc. need to be catered for. The ‘others’ line deals with all those values not explicitly described. Working with groups of bits: A basic pattern of bits is written in quotes as: “1”, “10101” etc. Testing a group of bits: IF bus4 = "0000" then .. Concatenating patterns and signals can be done using the operator ‘&’. e.g. if A, B and C are std_logic, then A&B&C is a three bit group. This construct can be useful in test expressions e.g. If A&B&C = "101" then .. If a sub group of a vector is needed, signals can be described specifically using indexes in brackets or as groups. Taking the example signal vector, bus4 : std_logic(3 downto 0), then individual and groups of bits can be referenced by: Bus4(1) -- bit 1 of the 4 bit bus Bus4(3 downto 1); -- the upper three bits of the vector Types and type conversion VHDL is a strongly typed language. It will not allow you to assign signals of one kind to another type. Here are the basic ones: Bits of std_logic_vector can be assigned to signals of std_logic e.g. Abit <= Bus4(2); Bus4 <= Abit & Bbit & Cbit & Dbit; Signals of ‘unsigned’ need to be type changed before assigning to std_logic and lengths ought to match. Using the following signal definitions: signal C : std_logic_vector(3 downto 0); signal C_us : unsigned(3 downto 0); The type cast is: C <= std_logic_vector(C_us); Numeric values such as constants need first to be converted to unsigned then to std_logic viz. C <= std_logic_vector(to_unsigned(11,4)); Interpret this line as: ‘take the number ‘11’ convert it to an unsigned number of 4 bits then assign that to a std_logic_vector of 4 bits. Page 21 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Defining ones own types. VHDL supports enumerated and user defined types. These must be defined in the architecture header where they are used. The statement is: type type_name is (..list of labels ..); e.g. type my_type is (S0,S1,S2,S3); The example defines a type with four values viz. S0, S1, S2, S3. These can be used in case statements etc. They can not be assigned to std_logic or ‘unsigned’ directly. In order to get these enumerated types out as logical signals (say on a PLD) a nested set of type conversions need to be performed. In the example below, Y is of the ‘my_type’ and X is std_logic_vector(3 downto 0): X <= std_logic_vector(to_unsigned(My_type'pos(Y),4)); This line is interpreted as: ‘take the current value of ‘Y’, find its position in the type definition list as a number (using signal attribute: ‘pos), convert the number to a 4 bit unsigned, convert the 4 bit unsigned to a 4 bit std_logic_vector. Synchronous and asynchronous working VHDL describes any logical circuit. A ‘clock’ signal is just another logical signal to VHDL. The basic VHDL constructs are asynchronous, in fact the language is driven by events and these (e.g. a change of level) can be on any of the signals in use. To design a function which is synchronous, clauses need to be used which pick out the events on the clock signal and use those to drive the synchronous portions. It is possible, therefore, that a function can implement both synchronous and asynchronous instructions. Triggering on events such as clock edges Since any circuit has to work on events, such as input changes or clock edges, it is necessary to be able to detect and check on signal states and events. In this basic case the clock is where edge events are most useful. To pick out and synchronize processing on clock edges, an attribute qualifier needs to be used on the clock signal. This qualifier is coded as a “ ‘event “ following the signal name. There are two ways to detect a clock event. The basic VHDL way: If clock’event and (clock = ’1’) then .. statements done on the rising edge of the clock .. Or (which may be dependant on the compiler in use as it relies on a function): If rising_edge(clock) then The “ ‘event ” qualifier to the clock signal test denotes an ‘attribute’ of the signal and it triggers when the signal has an event such as a rising edge. The rising edge is ascertained by looking for the (clock = ‘1’). So for a falling edge, use: if clock’event and (clock =’0’) then Page 22 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Mixing synchronous and asynchronous statements. Asynchronous statements need only be placed in the area of the code which is not encapsulated by a clock event IF. The skeleton here shows the form. Further examples are given later. Of course, IF statements need to be within a process. Process(..) begin .. statements done asynchronously .. If clock’event and (clock = ’1’) then .. End if; statements done on the rising edge of the clock .. .. stat End Process; ements done asynchronously .. Finite State Machines Finite state machines are best written in VHDL as separate processes which correspond to the fundamental blocks in Mealy and Moore machines viz. ‘next state logic’, ‘state memory’ and ‘output logic’. The state variable can be defined as std_logic_vector, or unsigned or, in the most flexible form, as a user defined state type. The architecture body should therefore take the form: Next_state_logic: process(inputs, current_state) Begin .. next state logic statements .. End process; State_memory: Process(clock) Begin memory latch .. .. state End Process; Out_put_logic: Process(Current_state, inputs) Begin .. output logic statements .. end process; Although counters are FSMs, since they rely on incrementing or decrementing numerical values, they can often be more simply written with numeric type assignments and not use the more general FSM form above. See the examples later. Specifying and modelling real circuits using delays Signal assignments can be made realistic by specifying a delay between inputs and outputs. This is done by including a timing parameter using the reserved word ‘after’. Here is an example for the assignment of signals within a simple AND gate: Y <= A and B after 10ns; Here the result Y is assigned 10ns after any changes in A or B. Here we have used VHDL’s default type of delay, called ‘inertial’ delay which models the operation of logical gates. This Page 23 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL inertial delay will not allow any input changes of faster than 10ns to pass through to Y. VHDL, of course, does allow more complex specification of delays, but for those, refer to a proper reference text. Considerations when fitting the VHDL design to a PLD. When fitting a VHDL coded function to a PLD the pins of the device need to be assigned. The fitter can be left to choose its own pins, or alternatively, specific pins can be assigned by the designer so that the device will match to the circuit under construction. The fitting of a VHDL design to a PLD will depend on both the VHDL development environment and target PLD in use. For some environments, the fitter can make use of ‘attribute’ statements to let it know which pins to use. These statements are placed after the Port definition in the entity header. Here we show the attributes recognised by Orcad (now rather old) and by Lattice Lever fitters: Entity thing is Port( … ); -- for ORcad Demo PLD fitter attribute PLDtype string; : attribute PLDtype of clock : signal is "clock"; attribute PLdtype of POR : signal is "in"; attribute PLDtype of Count : signal is "IO"; attribute PLDPIN : string; attribute PLDPIN of D : signal is "18,19,22,23"; Lattice Lever 22V10 fitter -- for attribute LOC : string; attribute LOC of width : signal is "8"; attribute LOC of phase_time : signal is "20,21,22,23"; Describing tri-state outputs A basic tri-state buffer has the schematic: En D Y When enabled, the output Y follows the input D. When enable is inactive, Y has a high impedance which, in VHDL std_logic, is a value Z. The following scrap of VHDL describes this function. process(D,en) begin if (en = '1') then Y <= D; else Y <= 'Z'; end process; end if; Page 24 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Circuit chunks Most circuits are made from known configurations and basic gates. Here are some basic fragments of VHDL for these elements. NOTE these may not be complete VHDL. D type latch: A positive edge triggered D type latch (input ‘data’, output Q). Data, clock and Q are std_logic. process(clock,Data) if rising_edge(clock) then Q <= d end if; ata; end process; Shift register: (8 bit parallel out ‘Q’): architecture behaviour of shift_8 is signal Regs : std_logic_vector(7 downto 0); begin process(Clock,SerIn,regs) begin if rising_edge(clock)then Regs <= Regs(6 downto 0)& SerIn; -- shift end if; end process; Q <= regs; -- output End behaviour; Counter; 4 bit up counter counter, positive edge triggered: signal count : unsigned(3 downto 0); .. Process(clock) begin if rising_edge(clock) then count <= count + 1; end if; end Process; Counter: 4 bit down counter, negative edge triggered with asynchronous reset. process(clock,Reset) begin if Reset = '1' then -- asynchronous reset Count <= "1111"; -- reset to ff else if clock’event and (clock =’0’) then Count <= Count - 1; -- down count on –ve edge end if; ; end process; end if Page 25 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Decoder: 2 to 4 line decoder with active low signal on output vector D. entity Decoder_2_To_4 is port A : in std_logic_vector (1 downto 0);( D : out std_logic_vector (3 downto 0)); end Decoder_2_To_4; architecture As_Case of Decode_2_To_4 is begin process )(A begin case A is when "01" => D <= "1101"; when "00" => D <= "1110"; when "10" => D <= "1011"; when "11" => D <= "0111"; when others => D <= "1111"; end case; end As_Case; end process; Multiplexer: 4 input (‘D’) multiplexer with a 2 bit select (‘S’) and one bit output ‘Y’: entity Multiplexer is port (S : in std_logic_vector (1 downto 0); D : in std_logic_vector (3 downto 0); end Multiplexer; Y : out std_logic); architecture behaviour of Multiplexer is begin process (S,D) begin case S is when "00" => Y <= D(0); when "01" => Y <= D(1); when "10" => Y <= D(2); when "11" => Y <= D(3); when others => Y <= D(0); end case; end process; end behaviour; Page 26 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Full examples These are full working VHDL entities which show examples of the basic constructs as described in the preceding manual. Assemblies of simple logic gates: library ieee; use ieee.std_logic_11 all;64. use ieee.numeric_std.all; entity Simp_logic_1 is port (A1,B1,A2,B2,A3,B3,A4,A5,B5,A6,B6 : in std_logic; Y1,Y2,Y3,Y4,Y5,Y6 : out std_logic); end Simp_logic_1; architecture behaviour of Simple_logic_1 is begin Y1 <= A1 and B1; Y2 <= A2 or B2; Y3 <= xor B3; A3 Y4 <= not A4; Y5 <= A5 nand B5; Y end behaviour; 6 <= A6 nor B6; A more complex assembly, using intermediate signals, which implements the circuit diagram below. B A C D Y T3ext T2 T1 T3 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Intermediate_variables is port (A,B,C,D : in std_logic; Y,T3EXT : out std_logic); end Intermediate_variables; architecture behaviour of Intermediate_variables is signal T1,T2,T3 :std_logic; begin T2 <= A and T1; T1 <= B or C; Y <= T2 or T3; T3 <= T1 and D; T3EXT <= T3; end behaviour; Page 27 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Complex combinational circuit making use of components. 4 bit adder. This circuit uses an entity for a one bit full adder as components to build a four bit full adder. The simple one bit full adder, uses the basic Boolean equations. The VHDL is: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity add_as_expressions is port( a,b,Cin : IN std_logic; S,Cout : out Std_Logic); end add_as_expressions; architecture behaviour of add_as_expressions is begin s <= A xor B xor Cin; Cout <= (A and B) or (Cin and B) or (Cin and A); end behaviour; The full 4 bit circuit is built from the one bit component. The links between components are shown on the circuit diagram below: C0 C1 C2SUM A0 B0 Cin SUM A1 B1 SUM A2 B2 SUM A3 B3 C3 CoutS0 S1 S2 S3 The VHDL is: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity four_bit_adder is port (a,b : in std_logic_vector (3 downto 0); Cin : in std_logic; s : out d_logic_vector (3 downto 0); st Cout : out std_logic); end four_bit_adder; architecture behaviour of four_bit_adder is component full_adder port (A, B, Cin : in std_logic; S, Cout : out std_logic); end component; C : st begin signal d_logic_vector (3 downto 0); Bit0: full_adder port map (a(0),b(0),Cin,S(0),C(0)); Bit1: full_adder port map (a(1),b(1),C(0),S(1),C(1)); Bit2: full_adder port map (a(2),b(2),C(1),S(2),C(2)); Bit3: full_adder port map (a(3),b(3),C(2),S(3),C(3)); BitOut: Cout <= C(3); end behaviour; Page 28 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Complex combinational circuit making use of components and processes. A 4 to 16 line decoder composed of 4 x 2 to 4 line decoders. In this implementation of a 2 to 4 line decoder the VHDL makes use of a case statement. The decoder has also an active low enable ‘Ebar’. (the IEEE libraries are omitted to save space): entity Decoder_2_To_4 is port (A : in std_logic_vector (1 downto 0); EBar in std_logic ; Ebar A1 A0 Ebar A1 A0 Ebar A1 A0 Ebar A1 A0 Ebar A1 A0 0 A3 A2 A1 A0 D0 D15 E0 E3 : D : out std_logic_vector (3 downto 0)); end Decoder_2_To_4; architecture behaviour of Decoder_2_To_4 is begin process(Ebar, A) begin if (Ebar = '0') then case A is when "00" => D <= "1110"; when "01" => D <= "1101"; when "10" => D <= "1011"; when "11" => D <= "0111"; when others => D <= "1111"; end case; else D <= "1111"; end if; end process; end behaviour; The full 4 to 16 line decoder is composed of five 2 to 4 decoders connected as in the diagram. The VHDL shows assignment of parts of vectors: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Decoder_4_To_16 is port (A : in std_logic_vector (3 downto 0); EBar : in std_logic; D : out std_logic_vector (15 downto 0)); end Decoder_4_To_16; architecture behaviour of Decoder_4_To_16 is component Decoder_2_To_4 is port (A : in std_logic_vector (1 downto 0); EBar : in std_logic ; D : out std_logic_vector (3 downto 0)); end component; signal EInt : std_logic_vector (3 downto 0); begin Decode_Master: Decoder_2_To_4 port map (A(3 downto 2), EBar, EInt); Decode_0: Decoder_2_To_4 port map (A(1 downto 0), EInt(0) , D(3 downto 0)); Decode_1: Decoder_2_To_4 port map (A(1 downto 0), EInt(1) , D(7 downto 4)); Decode_2: Decoder_2_To_4 port map (A(1 downto 0), EInt(2) , D(11 downto 8)); Decode_3: Decoder_2_To_4 port map (A(1 downto 0), EInt(3) , D(15 downto 12)); end behaviour; Page 29 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Combinational circuit with latching The VHDL example shows a BCD to 7 segment decoder with a D latch to hold the BCD value. It mimics the 4511 MSI chip. It has lamp test and blanking inputs also. Library ieee; use ieee.std_logic_11 all;64. use ieee.numeric_std.all; entity Seven_Segment_Display_latched is port(Count : in std_logic_vector(3 downto 0); LatchBar,LTBar,BLBar : in Std_logic; end Seven_Segment_Display_latched; a,b,c,d,e,f,g : out std_logic); architecture behaviour of Seven_Segment_Display_latched is signal Seven_Segments : std_logic_vector(6 downto 0); signal std_logic_vector(3 downto 0);BCDInt : begin process(Count,LatchBar) begin if LAtchBar = '1' then -- latching via transparent latch BCdInt <= Count; else BCDInt <= BcdInt; end if; end process; process(BCDInt,LtBar,BlBar) begin if (LTBar = '0') then -- lamp test Seven_segments <= "1111111"; else if BLBar = '0' then -- blanking seven_segments <= "0000000"; else case BcdInt is when "0000" => Seven_Segments <= "1111110"; -- 0 when "0001" => Seven_Segments <= "0110000"; -- 1 when "0010" => Seven_Segments <= "1101101"; -- 2 when "0011" => Seven_Segments <= "1111001"; -- 3 when "0100" => Seven_Segments <= "0110011"; -- 4 when "0101" => Seven_Segments <= "1011011"; -- 5 when "0110" => Seven_Segments <= "0011111"; -- 6 when "0111" => Seven_Segments <= "1110000"; -- 7 when "1000" => Seven_Segments <= "1111111"; -- 8 when "1001" => Seven_Segments <= "1110011"; -- 9 when "1010" => Seven_Segments <= "1110111"; -- A when "1011" => Seven_Segments <= "0011111"; -- b when "1100" => Seven_Segments <= "1001110"; -- C when "1101" => Seven_Segments <= "0111101"; -- d when "1110" => Seven_Segments <= "1001111"; -- E when "1111" => Seven_Segments <= "1000111"; -- F when others => Seven_Segments <= "0000000"; -- blank end case; end if; end if; end process; a <= Seven_Segments(6); -- assignment of LED signals b <= Seven_Segments(5); c <= Seven_Segments(4); d <= Seven_Segments(3); e <= Seven_Segments(2); f <= Seven_Segments(1); g <= Seven_Segments(0); end behaviour; Page 30 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Counters A four bit counter similar in function to the 74163 MSI chip. It has synchronous clear to 0, synchronous parallel load, two enables EnT, EnP, and one output ‘RCO’ which is active on the last count of 15. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity counter163 is port(clock,EnT,EnP,LoadBar,ClrBar : in std_logic; D : in std_logic_vector (3 downto 0); Count : out std_logic_vector(3 downto 0); RCO : out Std_logic); end Counter163; architecture behaviour of counter163 is signal Count_Int : unsigned(3 downto 0); signal RCO_int : std_logic; begin Counter: process(clock,EnP,EnT,LoadBar,ClrBar) begin if then rising_edge(clock) if Clrbar = '0' then Count_Int <= "0000"; -- reset to zero else if LoadBar = '0' then COunt_Int <= D; -- parallel load from inputs; else if (EnP ='1') and (EnT ='1') then COunt_int <= Count_int +1; end if; end if; end if; end if; end process; -- of doing counter stuff Outputs: process(Count_int, EnT) -- deal with output of RCO begin if (count_int = 15) and (Ent = '1') then RCO <= '1'; else RCO <= '0'; end if; end Process; C end behaviour; Ount <= std_logic_vector(Count_Int); -- assign count Page 31 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL A 5-bit count down timer with wait on 0, asynchronous load, and enable. The count sequence is count down but it does not roll past zero. The load is asynchronous, that is it does not wait for a rising clock edge, it loads the counter immediately from the data on ‘delay’. Library ieee; use ieee.std_logic_11 all;64. use ieee.numeric_std.all; entity timer is port(Clock,En,LoadB : in Std_logic; Delay : in std_logic_vector(5 downto 0); end timer; time_out : out std_logic); architecture behaviour of timer is signal Count : unsigned(5 downto 0); begin Count_down: Process(clock,En,LoadB) begin if LoadB = '0' then -- asynchronous load of data count <= Delay; -- set delay value else if rising_edge(clock) and (En = '1')then if count = "000000" then count <= "000000"; -- hold at zero else count end if; <= count - 1; -- count down else count <= count; -- wait for enable end if; end Process; end if; outputs : process(count,En) begin if (count = "0000") and (en = '1')then Time_out <= '1'; else Time_out <= '0'; end if; end behaviour; end process; Page 32 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Finite State machines The first example is a state machine (of type Moore) which produces a burst of outputs on W,X,Y when triggered by an input signal. The state diagram is: T = 1 T = 0 S3 [000] S0 [100] S1 [111] S2 [110] The VHDL code follows the FSM pattern of having processes for next state logic, state memory and output logic. The state coding is explicit. A case statement is used to model the state transition table. library ieee; use ieee.std_logic_11 all;64. use ieee.numeric_std.all; entity T_seq is port(clock,T : in std_logic; State_out : out std_logic_vector(1 downto 0); W,X,Y : out Std_logic); end T_Seq; architecture behaviour of T_Seq is signal unsigned(1 downto 0); Ccurrent,Cnext : begin State_register : process(clock) begin if _edge(clock) then Ccurrent <= Cnext; end if; rising end process; Next_state : process(Ccurrent,T) begin case Ccurrent is when "00" => Cnext <= "01"; when "01" => Cnext <= "10"; when "10" => Cnext <= "11"; when "11" => if T = '0' then Cnext <= "11"; -- wait else Cnext <= "00"; -- trigger end if; when others => Cnext <= "11"; -- safety assignment end case; end process; Outputs : process(CCurrent) begin case Ccurrent is when "00" => W <= '1'; X <= '0'; Y <= '0'; when "01" => W <= '1'; X <= '1'; Y <= '1'; when "10" => W <= '1'; X <= '1'; Y <= '0'; when "11" => W <= '0'; X <= '0'; Y <= '0'; when others => W <= '0'; X <= '0'; Y <= '0'; end case; end process; State_out <= std_logic_vector(Ccurrent); -- state output end behaviour; Page 33 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL Finite state machine with both Moore and Mealy type outputs. This example implements the state diagram below. It is a sequence detector detecting the sequence 0101 in the input ‘I’ which is assumed to be a serial data stream. Explicit state assignment has not been used, instead a user defined enumerated type called ‘State_type’ has been defined which uses the state names as labels. The VHDL can model the machine without having explicit state assignments. Deciding on the state assignment can be done at the fitting stage when the design has to be realised in hardware such as a PLD. R= 0 /11 I = 0 /01 R = 1 /00 I = 1 /00 I = 0 /01 I = 1 /00 I = 1 /01 I = 0 /01 I = 1 /11 Got_0 [01] Got_01 [01] Gotcha [11] Got_010 [01] Armed [00] I = 0 /01 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Sequence_detector is port(Clock,I,R : in std_logic; Mealy_X,Moore_Y : out std_logic_vector(1 downto 0)); end Sequence_detector; architecture behaviour of Sequence_detector is type tate_type is (armed,Got_0,Got_01,Got_010,Gotcha); S signal S_Current, S_Next : state_type; signal X,Y : std_logic_vector(1 downto 0); begin Stat process(clock)e_mem : begin if rising_edge(clock) then S_current <= S_next; end if; end process; Next process(S_current,I,R)_logic : begin case S_current is when armed => if I = '1' then S_next <= armed; end if; Else S_next <= got_0; when got_0 => if I = '1' then S_next <= got_01; Else S_next <= got_0; end if; when got_01 => if I = '1' then S_next <= armed; end if; else S_next <= got_010; when got_010 => if I = '1' then S_next <= gotcha; end if; else S_next <= got_0; when gotcha => if R = '1' then S_next <= armed; -- reset else S_next <= gotcha; end if; when others => S_next <= armed; end process; end case; Page 34 of 35 Continue Overleaf Digital Electronics 2 Simple Guide to VHDL outputs_Moore : process(s_current) begin case S_current is when armed => Y <= "00"; when got_0 => Y <= "01"; when got_01 => Y <= "01"; when got_010 => Y <= "01"; when gotcha => Y <= "11"; when others => Y <= "00"; end case; end process; outputs_Mealy: process(S_current,I,R) begin case S_current is when armed => if I = '1' then X <= "00"; end if; else X <= "01"; when got_0 => if I = '1' then X <= "01"; else X <= "01"; end if; when got_01 => if I = '1' then X <= "00"; end if; else X <= "01"; when got_010 => if I = '1' then X <= "11"; else X <= "01"; end if; when gotcha => if R = '1' then X <= "00"; -- reset else X <= "11"; end if; when others => X <= "00"; end case; end process; Mealy_X <= X; Moore_Y <= Y; end behaviour; Page 35 of 35 End of Question Paper
欢迎咨询51作业君