ASICs...THE COURSE (1 WEEK) 1 VHDL Key terms and concepts: syntax and semantics ? identifiers (names) ? entity and architecture ? package and library ? interface (ports) ? types ? sequential statements ? operators ? arithmetic ? concurrent statements ? execution ? configuration and specification History: U.S. Department of Defense (DoD) ? VHDL (VHSIC hardware description language) ? VHSIC (very high-speed IC) program? Institute of Electrical and Electronics Engineers (IEEE) ? IEEE Standard 1076-1987 and 1076-1993 ? MIL-STD-454 ? Language Reference Manual (LRM) 10.1 A Counter Key terms and concepts: VHDL keywords ? parallel programming language ? VHDL is a hardware description language ? analysis (the VHDL word for “compiled”) ? logic description, simulation, and synthesis entity Counter_1 is end; -- declare a "black box" called Counter_1 library STD; use STD.TEXTIO.all; -- we need this library to print architecture Behave_1 of Counter_1 is -- describe the "black box" -- declare a signal for the clock, type BIT, initial value '0' signal Clock : BIT := '0'; -- declare a signal for the count, type INTEGER, initial value 0 signal Count : INTEGER := 0; begin process begin -- process to generate the clock wait for 10 ns; -- a delay of 10 ns is half the clock cycle Clock <= not Clock; if (now > 340 ns) then wait; end if; -- stop after 340 ns end process; -- process to do the counting, runs concurrently with other processes process begin -- wait here until the clock goes from 1 to 0 wait until (Clock = '0'); -- now handle the counting 10 2 SECTION 10 VHDL ASICS... THE COURSE if (Count = 7) then Count <= 0; else Count <= Count + 1; end if; end process; process (Count) variable L: LINE; begin -- process to print write(L, now); write(L, STRING'(" Count=")); write(L, Count); writeline(output, L); end process; end; > vlib work > vcom Counter_1.vhd Model Technology VCOM V-System VHDL/Verilog 4.5b -- Loading package standard -- Compiling entity counter_1 -- Loading package textio -- Compiling architecture behave_1 of counter_1 > vsim -c counter_1 # Loading /../std.standard # Loading /../std.textio(body) # Loading work.counter_1(behave_1) VSIM 1> run 500 # 0 ns Count=0 # 20 ns Count=1 (...15 lines omitted...) # 340 ns Count=1 VSIM 2> quit > 10.2 A 4-bit Multiplier ? An example to motivate the study of the syntax and semantics of VHDL ? We wil multiply two 4-bit numbers by shifting and adding ? We need: two shift-registers, an 8-bit adder, and a state-machine for control ? This is an inefficient algorithm, but will illustrate how VHDL is “put together” ? We would not build/synthesize a real multiplier like this! ASICs... THE COURSE 10.2 A 4-bit Multiplier 3 10.2.1 An 8-bit Adder A full adder entity Full_Adder is generic (TS : TIME := 0.11 ns; TC : TIME := 0.1 ns); port (X, Y, Cin: in BIT; Cout, Sum: out BIT); end Full_Adder; architecture Behave of Full_Adder is begin Sum <= X xor Y xor Cin after TS; Cout <= (X and Y) or (X and Cin) or (Y and Cin) after TC; end; Timing: TS (Input to Sum) = 0.11 ns TC (Input to Cout) = 0.1 ns An 8-bit ripple-carry adder entity Adder8 is port (A, B: in BIT_VECTOR(7 downto 0); Cin: in BIT; Cout: out BIT; Sum: out BIT_VECTOR(7 downto 0)); end Adder8; architecture Structure of Adder8 is component Full_Adder port (X, Y, Cin: in BIT; Cout, Sum: out BIT); end component; signal C: BIT_VECTOR(7 downto 0); begin Stages: for i in 7 downto 0 generate LowBit: if i = 0 generate FA:Full_Adder port map (A(0),B(0),Cin,C(0),Sum(0)); end generate; OtherBits: if i /= 0 generate FA:Full_Adder port map (A(i),B(i),C(i-1),C(i),Sum(i)); end generate; end generate; Cout <= C(7); end; Cin Cout SumXY + Sum(7)A(7)B(7) Sum(6)A(6)B(6) Sum(5)A(5)B(5) Sum(4)A(4)B(4) Sum(3)A(3)B(3) Sum(2)A(2)B(2) Sum(1)A(1)B(1) Sum(0)A(0)B(0) Cout Cin SumAB Cin Cout8 8 Σ++ 8 ++ ++ ++ ++ 4 SECTION 10 VHDL ASICS... THE COURSE 10.2.2 A Register Accumulator Positive-edge–triggered D flip-flop with asynchronous clear entity DFFClr is generic(TRQ : TIME := 2 ns; TCQ : TIME := 2 ns); port (CLR, CLK, D : in BIT; Q, QB : out BIT); end; architecture Behave of DFFClr is signal Qi : BIT; begin QB <= not Qi; Q <= Qi; process (CLR, CLK) begin if CLR = '1' then Qi <= '0' after TRQ; elsif CLK'EVENT and CLK = '1' then Qi <= D after TCQ; end if; end process; end; Timing: TRQ (CLR to Q/QN) = 2ns TCQ (CLK to Q/QN) = 2ns An 8-bit register entity Register8 is port (D : in BIT_VECTOR(7 downto 0); Clk, Clr: in BIT ; Q : out BIT_VECTOR(7 downto 0)); end; architecture Structure of Register8 is component DFFClr port (Clr, Clk, D : in BIT; Q, QB : out BIT); end component; begin STAGES: for i in 7 downto 0 generate FF: DFFClr port map (Clr, Clk, D(i), Q(i), open); end generate; end; 8-bit register. Uses DFFClr positive edge- triggered flip-flop model. An 8-bit multiplexer entity Mux8 is generic (TPD : TIME := 1 ns); port (A, B : in BIT_VECTOR (7 downto 0); Sel : in BIT := '0'; Y : out BIT_VECTOR (7 downto 0)); end; architecture Behave of Mux8 is begin Y <= A after TPD when Sel = '1' else B after TPD; end; Eight 2:1 MUXs with single select input. Timing: TPD(input to Y)=1ns D QQNCLK CLR D Q Clk Clr 88 88 Sel01AB Y8 ASICs... THE COURSE 10.2 A 4-bit Multiplier 5 10.2.3 Zero Detector A zero detector entity AllZero is generic (TPD : TIME := 1 ns); port (X : BIT_VECTOR; F : out BIT ); end; architecture Behave of AllZero is begin process (X) begin F <= '1' after TPD; for j in X'RANGE loop if X(j) = '1' then F <= '0' after TPD; end if; end loop; end process; end; Variable-width zero detector. Timing: TPD(X to F) =1ns =0X Fn 6 SECTION 10 VHDL ASICS... THE COURSE 10.2.4 A Shift Register A variable-width shift register entity ShiftN is generic (TCQ : TIME := 0.3 ns; TLQ : TIME := 0.5 ns; TSQ : TIME := 0.7 ns); port(CLK, CLR, LD, SH, DIR: in BIT; D: in BIT_VECTOR; Q: out BIT_VECTOR); begin assert (D'LENGTH <= Q'LENGTH) report "D wider than output Q" severity Failure; end ShiftN; architecture Behave of ShiftN is begin Shift: process (CLR, CLK) subtype InB is NATURAL range D'LENGTH-1 downto 0; subtype OutB is NATURAL range Q'LENGTH-1 downto 0; variable St: BIT_VECTOR(OutB); begin if CLR = '1' then St := (others => '0'); Q <= St after TCQ; elsif CLK'EVENT and CLK='1' then if LD = '1' then St := (others => '0'); St(InB) := D; Q <= St after TLQ; elsif SH = '1' then case DIR is when '0' => St := '0' & St(St'LEFT downto 1); when '1' => St := St(St'LEFT-1 downto 0) & '0'; end case; Q <= St after TSQ; end if; end if; end process; end; CLK Clock CLR Clear, active high LD Load, active high SH Shift, active high DIR Direction, 1 = left D Data in Q Data out Variable-width shift register. Input width must be less than output width. Output is left-shifted or right-shifted under control of DIR. Unused MSBs are zero-padded during load. Clear is asynchronous. Loadis synchronous. Timing: TCQ (CLR to Q) = 0.3ns TLQ (LD to Q) = 0.5ns TSQ (SH to Q) = 0. 7ns D Q CLKDIRLD CLRSH n m ASICs... THE COURSE 10.2 A 4-bit Multiplier 7 10.2.5 A State Machine A Moore state machine for the multiplier entity SM_1 is generic (TPD : TIME := 1 ns); port(Start, Clk, LSB, Stop, Reset: in BIT; Init, Shift, Add, Done : out BIT); end; architecture Moore of SM_1 is type STATETYPE is (I, C, A, S, E); signal State: STATETYPE; begin Init <= '1' after TPD when State = I else '0' after TPD; Add <= '1' after TPD when State = A else '0' after TPD; Shift <= '1' after TPD when State = S else '0' after TPD; Done <= '1' after TPD when State = E else '0' after TPD; process (CLK, Reset) begin if Reset = '1' then State <= E; elsif CLK'EVENT and CLK = '1' then case State is when I => State <= C; when C => if LSB = '1' then State <= A; elsif Stop = '0' then State <= S; else State <= E; end if; when A => State <= S; when S => State <= C; when E => if Start = '1' then State <= I; end if; end case; end if; end process; end; State and function E End of multiply cycle. I Initialize: clear output register and load input registers. C Check if LSB of register A is zero. A Add shift register B to accumulator. S Shift input register A right and input register B left. C SShift=1 AAdd=1 IInit=1 E01 Done=1Start=1 LSB=1 LSB/Stop= 00 Start=0others Start ShiftDoneClk AddInitLSBStop 11 1 1 inputs outputs Reset Reset 8 SECTION 10 VHDL ASICS... THE COURSE 10.2.6 A Multiplier A 4-bit by 4-bit multiplier entity Mult8 is port (A, B: in BIT_VECTOR(3 downto 0); Start, CLK, Reset: in BIT; Result: out BIT_VECTOR(7 downto 0); Done: out BIT); end Mult8; architecture Structure of Mult8 is use work.Mult_Components.all; signal SRA, SRB, ADDout, MUXout, REGout: BIT_VECTOR(7 downto 0); signal Zero,Init,Shift,Add,Low:BIT := '0'; signal High:BIT := '1'; signal F, OFL, REGclr: BIT; begin REGclr <= Init or Reset; Result <= REGout; SR1 : ShiftN port map (CLK=>CLK,CLR=>Reset,LD=>Init,SH=>Shift,DIR=>Low ,D=>A,Q=>SRA); SR2 : ShiftN port map (CLK=>CLK,CLR=>Reset,LD=>Init,SH=>Shift,DIR=>High,D=>B,Q=>SRB); Z1 : AllZero port map (X=>SRA,F=>Zero); A1 : Adder8 port map (A=>SRB,B=>REGout,Cin=>Low,Cout=>OFL,Sum=>ADDout); M1 : Mux8 port map (A=>ADDout,B=>REGout,Sel=>Add,Y=>MUXout); R1 : Register8 port map (D=>MUXout,Q=>REGout,Clk=>CLK,Clr=>REGclr); F1 : SM_1 port map (Start,CLK,SRA(0),Zero,Reset,Init,Shift,Add,Done); end; D Q CLKDIRLD CLRSH D Q CLKDIRLD CLRSH Sum AB Cin Cout8 Σ+ + 8 A B CLK SR1 SR2 SRA SRB DQ ClkClr 88 SRA(0) Start ShiftDoneClk AddInitLSBStop REGout R1A1 F1 CLK Mult8 Result84 4 '0' OFL(not used) 8 8 Start CLK'0' '1' Shift Shift Init Init REGclr = Reset or Init Sel01AB Y M1 Z1 DoneReset Reset Reset ADDout AddReset Reset 8 MUXout FX F ShiftAddInit SM_1AllZero Register8 Mux8 Adder8ShiftN ShiftN =0 ASICs... THE COURSE 10.2 A 4-bit Multiplier 9 10.2.7 Packages and Testbench package Mult_Components is --1 component Mux8 port (A,B:BIT_VECTOR(7 downto 0); --2 Sel:BIT;Y:out BIT_VECTOR(7 downto 0));end component; --3 component AllZero port (X : BIT_VECTOR; --4 F:out BIT );end component; --5 component Adder8 port (A,B:BIT_VECTOR(7 downto 0);Cin:BIT; --6 Cout:out BIT;Sum:out BIT_VECTOR(7 downto 0));end component; --7 component Register8 port (D:BIT_VECTOR(7 downto 0); --8 Clk,Clr:BIT; Q:out BIT_VECTOR(7 downto 0));end component; --9 component ShiftN port (CLK,CLR,LD,SH,DIR:BIT;D:BIT_VECTOR; --10 Q:out BIT_VECTOR);end component; --11 component SM_1 port (Start,CLK,LSB,Stop,Reset:BIT; --12 Init,Shift,Add,Done:out BIT);end component; --13 end; --14 Utility code to help test the multiplier: package Clock_Utils is --1 procedure Clock (signal C: out Bit; HT, LT:TIME); --2 end Clock_Utils; --3 package body Clock_Utils is --4 procedure Clock (signal C: out Bit; HT, LT:TIME) is --5 begin --6 loop C<='1' after LT, '0' after LT + HT; wait for LT + HT; --7 end loop; --8 end; --9 end Clock_Utils; --10 Two functions for testing—to convert an array of bits to a number and vice versa: package Utils is --1 function Convert (N,L: NATURAL) return BIT_VECTOR; --2 function Convert (B: BIT_VECTOR) return NATURAL; --3 end Utils; --4 package body Utils is --5 function Convert (N,L: NATURAL) return BIT_VECTOR is --6 variable T:BIT_VECTOR(L-1 downto 0); --7 variable V:NATURAL:= N; --8 begin for i in T'RIGHT to T'LEFT loop --9 T(i) := BIT'VAL(V mod 2); V:= V/2; --10 end loop; return T; --11 end; --12 function Convert (B: BIT_VECTOR) return NATURAL is --13 variable T:BIT_VECTOR(B'LENGTH-1 downto 0) := B; --14 10 SECTION 10 VHDL ASICS... THE COURSE variable V:NATURAL:= 0; --15 begin for i in T'RIGHT to T'LEFT loop --16 if T(i) = '1' then V:= V + (2**i); end if; --17 end loop; return V; --18 end; --19 end Utils; --20 The following testbench exercises the multiplier model: entity Test_Mult8_1 is end; -- runs forever, use break!! --1 architecture Structure of Test_Mult8_1 is --2 use Work.Utils.all; use Work.Clock_Utils.all; --3 component Mult8 port --4 (A, B : BIT_VECTOR(3 downto 0); Start, CLK, Reset : BIT; --5 Result : out BIT_VECTOR(7 downto 0); Done : out BIT); --6 end component; --7 signal A, B : BIT_VECTOR(3 downto 0); --8 signal Start, Done : BIT := '0'; --9 signal CLK, Reset : BIT; --10 signal Result : BIT_VECTOR(7 downto 0); --11 signal DA, DB, DR : INTEGER range 0 to 255; --12 begin --13 C: Clock(CLK, 10 ns, 10 ns); --14 UUT: Mult8 port map (A, B, Start, CLK, Reset, Result, Done); --15 DR <= Convert(Result); --16 Reset <= '1', '0' after 1 ns; --17 process begin --18 for i in 1 to 3 loop for j in 4 to 7 loop --19 DA <= i; DB <= j; --20 A<=Convert(i,A'Length);B<=Convert(j,B'Length); --21 wait until CLK'EVENT and CLK='1'; wait for 1 ns; --22 Start <= '1', '0' after 20 ns; wait until Done = '1'; --23 wait until CLK'EVENT and CLK='1'; --24 end loop; end loop; --25 for i in 0 to 1 loop for j in 0 to 15 loop --26 DA <= i; DB <= j; --27 A<=Convert(i,A'Length);B<=Convert(j,B'Length); --28 wait until CLK'EVENT and CLK='1'; wait for 1 ns; --29 Start <= '1', '0' after 20 ns; wait until Done = '1'; --30 wait until CLK'EVENT and CLK='1'; --31 end loop; end loop; --32 wait; --33 end process; --34 end; --35 ASICs... THE COURSE 10.3 Syntax and Semanticsof VHDL 11 10.3 Syntax and Semanticsof VHDL Key terms: syntax rules? Backus–Naur form (BNF) ? constructs ? semantic rules ? lexical rules sentence ::= subject verb object. subject ::= The|A noun object ::= [article] noun {, and article noun} article ::= the|a noun ::= man|shark|house|food verb ::= eats|paints ::= means "can be replaced by" | means "or" [] means "contents optional" {} means "contents can be left out, used once, or repeated" The following two sentences are correct according to the syntax rules: A shark eats food. The house paints the shark, and the house, and a man. Semantic rules tell us that the second sentence does not make much sense. 12 SECTION 10 VHDL ASICS... THE COURSE 10.4 Identifiers and Literals Key terms: nouns of VHDL ? identifiers ? literals ? VHDL is not case sensitive ? static (known at analysis) ? abstract literals (decimal or based) ? decimal literals (integer or real) ? character literals ? bit-string literals identifier ::= letter {[underline] letter_or_digit} |\graphic_character{graphic_character}\ s -- A simple name. S -- A simple name, the same as s. VHDL is not case sensitive. a_name -- Imbedded underscores are OK. -- Successive underscores are illegal in names: Ill__egal -- Names can't start with underscore: _Illegal -- Names can't end with underscore: Illegal_ Too_Good -- Names must start with a letter. -- Names can't start with a number: 2_Bad \74LS00\ -- Extended identifier to break rules (VHDL-93 only). VHDL \vhdl\ \VHDL\ -- Three different names (VHDL-93 only). s_array(0) -- A static indexed name (known at analysis time). s_array(i) -- A non-static indexed name, if i is a variable. entity Literals_1 is end; architecture Behave of Literals_1 is begin process variable I1 : integer; variable Rl : real; variable C1 : CHARACTER; variable S16 : STRING(1 to 16); variable BV4: BIT_VECTOR(0 to 3); variable BV12 : BIT_VECTOR(0 to 11); variable BV16 : BIT_VECTOR(0 to 15); begin -- Abstract literals are decimal or based literals. -- Decimal literals are integer or real literals. -- Integer literal examples (each of these is the same): I1 := 120000; Int := 12e4; Int := 120_000; -- Based literal examples (each of these is the same): I1 := 2#1111_1111#; I1 := 16#FFFF#; -- Base must be an integer from 2 to 16: I1 := 16:FFFF:; -- you may use a : if you don't have # ASICs... THE COURSE 10.5 Entities and Architectures 13 -- Real literal examples (each of these is the same): Rl := 120000.0; Rl := 1.2e5; Rl := 12.0E4; -- Character literal must be one of the 191 graphic characters. -- 65 of the 256 ISO Latin-1 set are non-printing control characters C1 := 'A'; C1 := 'a'; -- different from each other -- String literal examples: S16 := " string" & " literal"; -- concatenate long strings S16 := """Hello,"" I said!"; -- doubled quotes S16 := % string literal%; -- can use % instead of " S16 := %Sale: 50%% off!!!%; -- doubled % -- Bit-string literal examples: BV4 := B"1100"; -- binary bit-string literal BV12 := O"7777"; -- octal bit-string literal BV16 := X"FFFF"; -- hex bit-string literal wait; end process; -- the wait prevents an endless loop end; 10.5 Entities and Architectures Key terms: design file (bookshelf) ? design units ? library units (book) ? library (collection of bookshelves) ? primary units ? secondary units (c.f. Table of Contents) ? entity declaration (black box) ? formal ports ( or formals) ? architecture body (contents of black box) ? visibility ? component declaration ? structural model ? local ports (or locals) ? instance names ? actual ports (or actuals) ? binding ? configuration declaration (a “shopping list”) ? design entity (entity–architecture pair) design_file ::= {library_clause|use_clause} library_unit {{library_clause|use_clause} library_unit} library_unit ::= primary_unit|secondary_unit primary_unit ::= entity_declaration|configuration_declaration|package_declaration secondary_unit ::= architecture_body|package_body 14 SECTION 10 VHDL ASICS... THE COURSE entity_declaration ::= entity identifier is [generic (formal_generic_interface_list);] [port (formal_port_interface_list);] {entity_declarative_item} [begin {[label:] [postponed] assertion ; |[label:] [postponed] passive_procedure_call ; |passive_process_statement}] end [entity] [entity_identifier] ; entity Half_Adder is port (X, Y : in BIT := '0'; Sum, Cout : out BIT); -- formals end; architecture_body ::= architecture identifier of entity_name is {block_declarative_item} begin {concurrent_statement} end [architecture] [architecture_identifier] ; architecture Behave of Half_Adder is begin Sum <= X xor Y; Cout <= X and Y; end Behave; Components: component_declaration ::= component identifier [is] [generic (local_generic_interface_list);] [port (local_port_interface_list);] end component [component_identifier]; architecture Netlist of Half_Adder is component MyXor port (A_Xor,B_Xor : in BIT; Z_Xor : out BIT); end component; -- component with locals component MyAnd port (A_And,B_And : in BIT; Z_And : out BIT); end component; -- component with locals ASICs... THE COURSE 10.5 Entities and Architectures 15 begin Xor1: MyXor port map (X, Y, Sum); -- instance with actuals And1 : MyAnd port map (X, Y, Cout); -- instance with actuals end; These design entities (entity–architecture pairs) would be part of a technology library: entity AndGate is port (And_in_1, And_in_2 : in BIT; And_out : out BIT); -- formals end; architecture Simple of AndGate is begin And_out <= And_in_1 and And_in_2; end; entity XorGate is port (Xor_in_1, Xor_in_2 : in BIT; Xor_out : out BIT); -- formals end; architecture Simple of XorGate is begin Xor_out <= Xor_in_1 xor Xor_in_2; end; configuration_declaration ::= configuration identifier of entity_name is {use_clause|attribute_specification|group_declaration} block_configuration end [configuration] [configuration_identifier] ; configuration Simplest of Half_Adder is use work.all; for Netlist for And1 : MyAnd use entity AndGate(Simple) port map -- association: formals => locals (And_in_1 => A_And, And_in_2 => B_And, And_out => Z_And); end for; for Xor1 : MyXor use entity XorGate(Simple) port map (Xor_in_1 => A_Xor, Xor_in_2 => B_Xor, Xor_out => Z_Xor); 16 SECTION 10 VHDL ASICS... THE COURSE end for; end for; end; Entities, architectures, components, ports, port maps, and configurations architecture Netlist of Half_Adder Xor_outXor_in_1 entityXorGateXor_in_2 FFF CoutSumXY entity Half_Adder And1 Xor1XY CoutSumAA AA for Xor1:MyXor use entity XorGate(Simple) port map component (Xor_in_1 => A_Xor, Xor_in_2 => B_Xor, Xor_out => Z_Xor);configuration Simplestof Half_Adder Xor1: MyXor port map (X, Y, Sum); port (A_Xor,B_Xor : in BIT; Z_Xor : out BIT) A_XorB_Xor Z_XorMyXor LLL Xor_out <= Xor_in_1 xor Xor_in_2; architecture Simpleof XorGate A actualF formal L local ports ASICs... THE COURSE 10.6 Packages and Libraries 17 10.6 Packages and Libraries Key terms: design library (the current working library or a resource library) ? working library (work) ? package ? package body ? package visibility ? library clause ? use clause package_declaration ::= package identifier is {subprogram_declaration | type_declaration | subtype_declaration | constant_declaration | signal_declaration | file_declaration | alias_declaration | component_declaration | attribute_declaration | attribute_specification | disconnection_specification | use_clause | shared_variable_declaration | group_declaration | group_template_declaration} end [package] [package_identifier] ; package_body ::= package body package_identifier is {subprogram_declaration | subprogram_body | type_declaration | subtype_declaration | constant_declaration | file_declaration | alias_declaration | use_clause | shared_variable_declaration | group_declaration | group_template_declaration} end [package body] [package_identifier] ; library MyLib; -- library clause use MyLib.MyPackage.all; -- use clause -- design unit (entity + architecture, etc.) follows: 10.6.1 Standard Package Key terms: STANDARD package (defined in the LRM ) ? TIME ? INTEGER ? REAL ? STRING ? CHARACTER ? I use uppercase for standard types ? ISO 646-1983 ? ASCII character set ? character codes ? graphic symbol (glyph) ? ISO 8859-1:1987(E) ? ISO Latin-1 package Part_STANDARD is type BOOLEAN is (FALSE, TRUE); type BIT is ('0', '1'); 18 SECTION 10 VHDL ASICS... THE COURSE type SEVERITY_LEVEL is (NOTE, WARNING, ERROR, FAILURE); subtype NATURAL is INTEGER range 0 to INTEGER'HIGH; subtype POSITIVE is INTEGER range 1 to INTEGER'HIGH; type BIT_VECTOR is array (NATURAL range <>) of BIT; type STRING is array (POSITIVE range <>) of CHARACTER; -- the following declarations are VHDL-93 only: attribute FOREIGN: STRING; -- for links to other languages subtype DELAY_LENGTH is TIME range 0 fs to TIME'HIGH; type FILE_OPEN_KIND is (READ_MODE,WRITE_MODE,APPEND_MODE); type FILE_OPEN_STATUS is (OPEN_OK,STATUS_ERROR,NAME_ERROR,MODE_ERROR); end Part_STANDARD; type TIME is range implementation_defined -- and varies with software units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ms; min = 60 sec; hr = 60 min; end units; type Part_CHARACTER is ( -- 128 ASCII characters in VHDL-87 NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, -- 33 control characters BS, HT, LF, VT, FF, CR, SO, SI, -- including: DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, -- format effectors: CAN, EM, SUB, ESC, FSP, GSP, RSP, USP, -- horizontal tab = HT ' ', '!', '"', '#', '$', '%', '&', ''', -- line feed = LF '(', ')', '*', '+', ',', '-', '.', '/', -- vertical tab = VT '0', '1', '2', '3', '4', '5', '6', '7', -- form feed = FF '8', '9', ':', ';', '<', '=', '>', '?', -- carriage return = CR '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', -- and others: 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', -- FSP, GSP, RSP, USP use P 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', -- suffix to avoid conflict 'X', 'Y', 'Z', '[', '\', ']', '^', '_', -- with TIME units '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', DEL -- delete = DEL -- VHDL-93 includes 96 more Latin-1 characters, like ¥ (Yen) and -- 32 more control characters, better not to use any of them. ); ASICs... THE COURSE 10.6 Packages and Libraries 19 10.6.2 Std_logic_1164 Package Key terms: logic-value system ? BIT ? '0' and '1' ? 'X' (unknown) ? 'Z' (high-impedance) ? metalogical value (simbits) ? Std_logic_1164 package ? MVL9—multivalued logic nine ? driver ? resolve ? resolution function ? resolved subtype STD_LOGIC ? unresolved type STD_ULOGIC ? subtypes are compatible with types ? overloading ? STD_LOGIC_VECTOR ? STD_ULOGIC_VECTOR ? don’t care logic value '-' (hyphen) type MVL4 is ('X', '0', '1', 'Z'); -- example of a four-value logic system library IEEE; use IEEE.std_logic_1164.all; -- to use the IEEE package package Part_STD_LOGIC_1164 is --1 type STD_ULOGIC is --2 ( 'U', -- Uninitialized --3 'X', -- Forcing Unknown --4 '0', -- Forcing 0 --5 '1', -- Forcing 1 --6 'Z', -- High Impedance --7 'W', -- Weak Unknown --8 'L', -- Weak 0 --9 'H', -- Weak 1 --10 '-' -- Don't Care); --11 type STD_ULOGIC_VECTOR is array (NATURAL range <>) of STD_ULOGIC; --12 function resolved (s : STD_ULOGIC_VECTOR) return STD_ULOGIC; --13 subtype STD_LOGIC is resolved STD_ULOGIC; --14 type STD_LOGIC_VECTOR is array (NATURAL range <>) of STD_LOGIC; --15 subtype X01 is resolved STD_ULOGIC range 'X' to '1'; --16 subtype X01Z is resolved STD_ULOGIC range 'X' to 'Z'; --17 subtype UX01 is resolved STD_ULOGIC range 'U' to '1'; --18 subtype UX01Z is resolved STD_ULOGIC range 'U' to 'Z'; --19 -- Vectorized overloaded logical operators: --20 function "and" (L : STD_ULOGIC; R : STD_ULOGIC) return UX01; --21 -- Logical operators not, and, nand, or, nor, xor, xnor (VHDL-93),--22 -- overloaded for STD_ULOGIC STD_ULOGIC_VECTOR STD_LOGIC_VECTOR. --23 -- Strength strippers and type conversion functions: --24 -- function To_T (X : F) return T; --25 -- defined for types, T and F, where --26 -- F=BIT BIT_VECTOR STD_ULOGIC STD_ULOGIC_VECTOR STD_LOGIC_VECTOR --27 -- T=types F plus types X01 X01Z UX01 (but not type UX01Z) --28 -- Exclude _'s in T in name: TO_STDULOGIC not TO_STD_ULOGIC --29 -- To_XO1 : L->0, H->1 others->X --30 20 SECTION 10 VHDL ASICS... THE COURSE -- To_XO1Z: Z->Z, others as To_X01 --31 -- To_UX01: U->U, others as To_X01 --32 -- Edge detection functions: --33 function rising_edge (signal s: STD_ULOGIC) return BOOLEAN; --34 function falling_edge (signal s: STD_ULOGIC) return BOOLEAN; --35 -- Unknown detection (returns true if s = U, X, Z, W): --36 -- function Is_X (s : T) return BOOLEAN; --37 -- defined for T = STD_ULOGIC STD_ULOGIC_VECTOR STD_LOGIC_VECTOR. --38 end Part_STD_LOGIC_1164; --39 10.6.3 Textio Package package Part_TEXTIO is -- VHDL-93 version. type LINE is access STRING; -- LINE is a pointer to a STRING value. type TEXT is file of STRING; -- File of ASCII records. type SIDE is (RIGHT, LEFT); -- for justifying output data. subtype WIDTH is NATURAL; -- for specifying widths of output fields. file INPUT : TEXT open READ_MODE is "STD_INPUT"; -- Default input file. file OUTPUT : TEXT open WRITE_MODE is "STD_OUTPUT"; -- Default output. -- The following procedures are defined for types, T, where -- T = BIT BIT_VECTOR BOOLEAN CHARACTER INTEGER REAL TIME STRING -- procedure READLINE(file F : TEXT; L : out LINE); -- procedure READ(L : inout LINE; VALUE : out T); -- procedure READ(L : inout LINE; VALUE : out T; GOOD: out BOOLEAN); -- procedure WRITELINE(F : out TEXT; L : inout LINE); -- procedure WRITE( -- L : inout LINE; -- VALUE : in T; -- JUSTIFIED : in SIDE:= RIGHT; -- FIELD:in WIDTH := 0; -- DIGITS:in NATURAL := 0; -- for T = REAL only ASICs... THE COURSE 10.6 Packages and Libraries 21 -- UNIT:in TIME:= ns); -- for T = TIME only -- function ENDFILE(F : in TEXT) return BOOLEAN; end Part_TEXTIO; Example: library std; use std.textio.all; entity Text is end; architecture Behave of Text is signal count : INTEGER := 0; begin count <= 1 after 10 ns, 2 after 20 ns, 3 after 30 ns; process (count) variable L: LINE; begin if (count > 0) then write(L, now); -- Write time. write(L, STRING'(" count=")); -- STRING' is a type qualification. write(L, count); writeline(output, L); end if; end process; end; 10 ns count=1 20 ns count=2 30 ns count=3 10.6.4 Other Packages Key terms: arithmetic packages ? Synopsys std_arith ? (mis)use of IEEE library ? math packages [IEEE 1076.2, 1996] ? synthesis packages ? component packages 10.6.5 Creating Packages Key terms: packaged constants ? linking the VHDL world and the real world package Adder_Pkg is -- a package declaration constant BUSWIDTH : INTEGER := 16; end Adder_Pkg; use work.Adder_Pkg.all; -- a use clause entity Adder is end Adder; architecture Flexible of Adder is -- work.Adder_Pkg is visible here begin process begin 22 SECTION 10 VHDL ASICS... THE COURSE MyLoop : for j in 0 to BUSWIDTH loop -- adder code goes here end loop; wait; -- the wait prevents an endless cycle end process; end Flexible; package GLOBALS is constant HI : BIT := '1'; constant LO: BIT := '0'; end GLOBALS; library MyLib; -- use MyLib.Add_Pkg.all; -- use all the package use MyLib.Add_Pkg_Fn.add; -- just function 'add' from the package entity Lib_1 is port (s : out BIT_VECTOR(3 downto 0) := "0000"); end; architecture Behave of Lib_1 is begin process begin s <= add ("0001", "0010", "1000"); wait; end process; end; There are three common methods to create the links between the file and directory names: ? Use a UNIX environment variable (SETENV MyLib ~/MyDirectory/MyLibFile, for example). ? Create a separate file that establishes the links between the filename known to the operating system and the library name known to the VHDL software. ? Include the links in an initialization file (often with an '.ini'suffix). ASICs... THE COURSE 10.7 Interface Declarations 23 10.7 Interface Declarations Key terms: interface declaration ? formals ? locals ? actuals ? interface objects (constants, signals, variables, or files) ? interface constants (generics of a design entity, a component, or a block, or parameters of subprograms) ? interface signals (ports of a design entity, component, or block, and parameters of subprograms) ? interface variables and interface files (parameters of subprograms) ? interface object mode (in,the default, out, inout, buffer, linkage) ? read ? update ? interface object rules (“i before e”), there are also mode rules (“except after c”) Modes of interface objects and their properties entity E1 is port (Inside : in BIT); end; architecture Behave of E1 is begin end; entity E2 is port (Outside : inout BIT := '1'); end; architecture Behave of E2 is component E1 port (Inside: in BIT); end component; signal UpdateMe : BIT; begin I1 : E1 port map (Inside => Outside); -- formal/local (mode in) => actual (mode inout) UpdateMe <= Outside; -- OK to read Outside (mode inout) Outside <= '0' after 10 ns; -- and OK to update Outside (mode inout) end; Possible modes of interface object, Outside in (default) out inout buffer Can you read Outside (RHS of assignment)? Yes No Yes Yes Can you update Outside (LHS of assignment)? No Yes Yes Yes Modes of Inside that Outside may connect to (see below) in out any any mode Y E2 InsideOutside means "legal to associate interfaceobject (Outside) of mode X withformal (Inside) of mode Y" mode X interface object:signal, variable,constant, or file E1F F formal A A actual ininout 1 2 3 45 67 8910 7 inout outin buffer X Y 24 SECTION 10 VHDL ASICS... THE COURSE 10.7.1 Port Declaration Key terms: ports (connectors)? port interface declaration ? formals ? locals ? actuals ? implicit signal declaration ? port mode ? signal kind ? default value ? default expression ? open ? port map ? positional association ? named association ? default binding Properties of ports Example entity declaration: entity E is port (F_1:BIT; F_2:out BIT; F_3:inout BIT; F_4:buffer BIT); end; -- formals Example component declaration: component C port (L_1:BIT; L_2:out BIT; L_3:inout BIT; L_4:buffer BIT); -- locals end component; Example component instantiation: I1 : C port map (L_1 => A_1,L_2 => A_2,L_3 => A_3,L_4 => A_4); -- locals => actuals Example configuration: for I1 : C use entity E(Behave) port map (F_1 => L_1,F_2 => L_2,F_3 => L_3,F_4 => L_4); -- formals => locals Interface object, port F F_1 F_2 F_3 F_4 Mode of F in (default) out inout buffer Can you read attributes of F? [VHDL LRM4.3.2] Yes, but not the attributes: 'STABLE 'QUIET 'DELAYED 'TRANSACTION Yes, but not the attributes: 'STABLE 'QUIET 'DELAYED 'TRANSACTION 'EVENT 'ACTIVE 'LAST_EVENT 'LAST_ACTIVE 'LAST_VALUE Yes, but not the attributes: 'STABLE 'QUIET 'DELAYED 'TRANSACTION Yes ASICs... THE COURSE 10.7 Interface Declarations 25 port (port_interface_list) interface_list ::= port_interface_declaration {; port_interface_declaration} interface_declaration ::= [signal] identifier {, identifier}:[in|out|inout|buffer|linkage] subtype_indication [bus] [:= static_expression] entity Association_1 is port (signal X, Y : in BIT := '0'; Z1, Z2, Z3 : out BIT); end; Connection rules for port modes entity E1 is port (Inside : in BIT); end; architecture Behave of E1 is begin end; entity E2 is port (Outside : inout BIT := '1'); end; architecture Behave of E2 is component E1 port (Inside : in BIT); end component; begin I1 : E1 port map (Inside => Outside); -- formal/local (mode in) => actual (mode inout) end; Possible modes of interface object, Inside in (default) out inout buffer Modes of Outside that Inside may connect to (see below) in inout buffer out inout inout 1 buffer2 1A signal of mode inout can be updated by any number of sources. 2A signal of mode buffer can be updated by at most one source. means "legal to associate formal port(Inside) of mode Y with actual port(Outside) of mode X" mode Y E2 InsideOutsidemode X E1F F formal A A actual ininout ports 1 2 3 45 67 7 outin inoutbuffer X Y 26 SECTION 10 VHDL ASICS... THE COURSE use work.all; -- makes analyzed design entity AndGate(Simple) visible. architecture Netlist of Association_1 is -- The formal port clause for entity AndGate looks like this: -- port (And_in_1, And_in_2: in BIT; And_out : out BIT); -- Formals. component AndGate port (And_in_1, And_in_2 : in BIT; And_out : out BIT); -- Locals. end component; begin -- The component and entity have the same names: AndGate. -- The port names are also the same: And_in_1, And_in_2, And_out, -- so we can use default binding without a configuration. -- The last (and only) architecture for AndGate will be used: Simple. A1:AndGate port map (X, Y, Z1); -- positional association A2:AndGate port map (And_in_2=>Y, And_out=>Z2, And_in_1=>X); -- named A3:AndGate port map (X, And_out => Z3, And_in_2 => Y); -- both end; entity ClockGen_1 is port (Clock : out BIT); end; architecture Behave of ClockGen_1 is begin process variable Temp : BIT := '1'; begin -- Clock <= not Clock; -- Illegal, you cannot read Clock (mode out), Temp := not Temp; -- use a temporary variable instead. Clock <= Temp after 10 ns; wait for 10 ns; if (now > 100 ns) then wait; end if; end process; end; 10.7.2 Generics Key terms: generic (similar to a port) ? ports (signals) carry changing information between entities ? generics carry constant, static information ? generic interface list entity AndT is generic (TPD : TIME := 1 ns); port (a, b : BIT := '0'; q: out BIT); end; architecture Behave of AndT is begin q <= a and b after TPD; end; ASICs... THE COURSE 10.7 Interface Declarations 27 entity AndT_Test_1 is end; architecture Netlist_1 of AndT_Test_1 is component MyAnd port (a, b : BIT; q : out BIT); end component; signal a1, b1, q1 : BIT := '1'; begin And1 : MyAnd port map (a1, b1, q1); end Netlist_1; configuration Simplest_1 of AndT_Test_1 is use work.all; for Netlist_1 for And1 : MyAnd use entity AndT(Behave) generic map (2 ns); end for; end for; end Simplest_1; 28 SECTION 10 VHDL ASICS... THE COURSE 10.8 Type Declarations Key terms and concepts: type of an object ? VHDL is strongly typed ? you cannot add a temperature of type Centigrade to a temperature of type Fahrenheit ? type declaration ? range ? precision ? subtype ? subtype declaration ? composite type (array type) ? aggregate notation ? record type There are four type classes: scalar types, composite types, access types, file types 1. Scalar types: integer type, floating-point type, physical type, enumeration type (integer and enumeration types are discrete types) (integer, floating-point, and physical types are numeric types) (physical types correspond to time, voltage, current, and so on and have dimensions) 2. Composite types include array types (and record types) 3. Access types are pointers, good for abstract data structures, less so in ASIC design 4. File types are used for file I/O, not ASIC design type_declaration ::= type identifier ; | type identifier is (identifier|'graphic_character' {, identifier|'graphic_character'}) ; | range_constraint ; | physical_type_definition ; | record_type_definition ; | access subtype_indication ; | file of type_name ; | file of subtype_name ; | array index_constraint of element_subtype_indication ; | array (type_name|subtype_name range <> {, type_name|subtype_name range <>}) of element_subtype_indication ; entity Declaration_1 is end; architecture Behave of Declaration_1 is type F is range 32 to 212; -- Integer type, ascending range. type C is range 0 to 100; -- Range 0 to 100 is the range constraint. subtype G is INTEGER range 9 to 0; -- Base type INTEGER, descending. -- This is illegal: type Bad100 is INTEGER range 0 to 100; -- don't use INTEGER in declaration of type (but OK in subtype). type Rainbow is (R, O, Y, G, B, I, V); -- An enumeration type. -- Enumeration types always have an ascending range. type MVL4 is ('X', '0', '1', 'Z'); ASICs... THE COURSE 10.8 Type Declarations 29 -- Note that 'X' and 'x' are different character literals. -- The default initial value is MVL4'LEFT = 'X'. -- We say '0' and '1' (already enumeration literals -- for predefined type BIT) are overloaded. -- Illegal enumeration type: type Bad4 is ("X", "0", "1", "Z"); -- Enumeration literals must be character literals or identifiers. begin end; entity Arrays_1 is end; architecture Behave of Arrays_1 is type Word is array (0 to 31) of BIT; -- a 32-bit array, ascending type Byte is array (NATURAL range 7 downto 0) of BIT; -- descending type BigBit is array (NATURAL range <>) of BIT; -- We call <> a box, it means the range is undefined for now. -- We call BigBit an unconstrained array. -- This is OK, we constrain the range of an object that uses -- type BigBit when we declare the object, like this: subtype Nibble is BigBit(3 downto 0); type T1 is array (POSITIVE range 1 to 32) of BIT; -- T1, a constrained array declaration, is equivalent to a type T2 -- with the following three declarations: subtype index_subtype is POSITIVE range 1 to 32; type array_type is array (index_subtype range <>) of BIT; subtype T2 is array_type (index_subtype); -- We refer to index_subtype and array_type as being -- anonymous subtypes of T1 (since they don't really exist). begin end; entity Aggregate_1 is end; architecture Behave of Aggregate_1 is type D is array (0 to 3) of BIT; type Mask is array (1 to 2) of BIT; signal MyData : D := ('0', others => '1'); -- positional aggregate signal MyMask : Mask := (2 => '0', 1 => '1'); -- named aggregate begin end; entity Record_2 is end; architecture Behave of Record_2 is type Complex is record real : INTEGER; imag : INTEGER; end record; signal s1 : Complex := (0, others => 1); signal s2: Complex; begin s2 <= (imag => 2, real => 1); end; 30 SECTION 10 VHDL ASICS... THE COURSE 10.9 Other Declarations Key concepts: (we already covered entity, configuration, component, package, interface, type, and subtype declarations) ? objects: constant, variable, signal, file ? alias (user-defined “monikers”) ? attributes (user-defined and tool-vendor defined) ? subprograms: functions and procedures ? groups and group templates are new to VHDL-93 and hardly used in ASIC design declaration ::= type_declaration | subtype_declaration | object_declaration | interface_declaration | alias_declaration | attribute_declaration | component_declaration | entity_declaration | configuration_declaration | subprogram_declaration | package_declaration | group_template_declaration | group_declaration 10.9.1 Object Declarations Key terms and concepts: class of an object ? declarative region (before the first begin) ? declare a type with (explicit) initial value ? (implicit) default initial value is T'LEFT? explicit signal decla- rations ? shared variable There are four object classes: constant, variable, signal, file You use a constant declaration, signal declaration, variable declaration, or file declaration together with a type Signals represent real wires in hardware Variables are memory locations in a computer entity Initial_1 is end; architecture Behave of Initial_1 is type Fahrenheit is range 32 to 212; -- Default initial value is 32. type Rainbow is (R, O, Y, G, B, I, V); -- Default initial value is R. type MVL4 is ('X', '0', '1', 'Z'); -- MVL4'LEFT = 'X'. begin end; ASICs... THE COURSE 10.9 Other Declarations 31 constant_declaration ::= constant identifier {, identifier}:subtype_indication [:= expression] ; signal_declaration ::= signal identifier {, identifier}:subtype_indication [register|bus] [:=expression]; entity Constant_2 is end; library IEEE; use IEEE.STD_LOGIC_1164.all; architecture Behave of Constant_2 is constant Pi : REAL := 3.14159; -- A constant declaration. signal B : BOOLEAN; signal s1, s2: BIT; signal sum : INTEGER range 0 to 15; -- Not a new type. signal SmallBus : BIT_VECTOR(15 downto 0); -- 16-bit bus. signal GBus : STD_LOGIC_VECTOR(31 downto 0) bus; -- A guarded signal. begin end; variable_declaration ::= [shared] variable identifier {, identifier}:subtype_indication [:= expression] ; library IEEE; use IEEE.STD_LOGIC_1164.all; entity Variables_1 is end; architecture Behave of Variables_1 is begin process variable i : INTEGER range 1 to 10 := 10; -- Initial value = 10. variable v : STD_LOGIC_VECTOR (0 to 31) := (others => '0'); begin wait; end process; -- The wait stops an endless cycle. end; 32 SECTION 10 VHDL ASICS... THE COURSE 10.9.2 Subprogram Declarations Key terms and concepts: subprogram ? function ? procedure ? subprogram declaration: a function declaration or a procedure declaration ? formal parameters (or formals) ? subprogram invocation ? actual parameters (or actuals) ? impure function (now) ? pure function (default) ? subprogram specification ? subprogram body ? conform ? private subprogram_declaration ::= subprogram_specification ; ::= procedure identifier|string_literal [(parameter_interface_list)] Properties of subprogram parameters Example subprogram declarations: function my_function(Ff) return BIT is -- Formal function parameter, Ff. procedure my_procedure(Fp); -- Formal procedure parameter, Fp. Example subprogram calls: my_result := my_function(Af); -- Calling a function with an actual parameter, Af. MY_LABEL:my_procedure(Ap); -- Using a procedure with an actual parameter, Ap. Mode of Ff or Fp (formals) in out inout No mode Permissible classes for Af (function actual parameter) constant (default) signal Not allowed Not allowed file Permissible classes for Ap (procedure actual parame- ter) constant (default) variable signal constant variable (default) signal constant variable (default) signal file Can you read attributes of Ff or Fp (formals)? Yes, except: 'STABLE 'QUIET 'DELAYED 'TRANSACTION of a signal Yes, except: 'STABLE 'QUIE T 'DELAYED 'TRANSACTION 'EVENT 'ACTIV E 'LAST_EVENT 'LAST_ACTIVE 'LAST_VALUE of a signal Yes, except: 'STABLE 'QUIET 'DELAYED 'TRANSACTION of a signal ASICs... THE COURSE 10.9 Other Declarations 33 | [pure|impure] function identifier|string_literal [(parameter_interface_list)] return type_name|subtype_name; function add(a, b, c : BIT_VECTOR(3 downto 0)) return BIT_VECTOR is -- A function declaration, a function can't modify a, b, or c. procedure Is_A_Eq_B (signal A, B : BIT; signal Y : out BIT); -- A procedure declaration, a procedure can change Y. subprogram_body ::= subprogram_specification is {subprogram_declaration|subprogram_body |type_declaration|subtype_declaration |constant_declaration|variable_declaration|file_declaration |alias_declaration|attribute_declaration|attribute_specification |use_clause|group_template_declaration|group_declaration} begin {sequential_statement} end [procedure|function] [identifier|string_literal] ; function subset0(sout0 : in BIT) return BIT_VECTOR -- declaration -- Declaration can be separate from the body. function subset0(sout0 : in BIT) return BIT_VECTOR is -- body variable y : BIT_VECTOR(2 downto 0); begin if (sout0 = '0') then y := "000"; else y := "100"; end if; return result; end; procedure clockGen (clk : out BIT) -- Declaration procedure clockGen (clk : out BIT) is -- Specification begin -- Careful this process runs forever: process begin wait for 10 ns; clk <= not clk; end process; end; 34 SECTION 10 VHDL ASICS... THE COURSE entity F_1 is port (s : out BIT_VECTOR(3 downto 0) := "0000"); end; architecture Behave of F_1 is begin process function add(a, b, c : BIT_VECTOR(3 downto 0)) return BIT_VECTOR is begin return a xor b xor c; end; begin s <= add("0001", "0010", "1000"); wait; end process; end; package And_Pkg is procedure V_And(a, b : BIT; signal c : out BIT); function V_And(a, b : BIT) return BIT; end; package body And_Pkg is procedure V_And(a,b : BIT;signal c : out BIT) is begin c <= a and b; end; function V_And(a,b : BIT) return BIT is begin return a and b; end; end And_Pkg; entity F_2 is port (s: out BIT := '0'); end; use work.And_Pkg.all; -- use package already analyzed architecture Behave of F_2 is begin process begin s <= V_And('1', '1'); wait; end process; end; 10.9.3 Alias and Attribute Declarations alias_declaration ::= alias identifier|character_literal|operator_symbol [ :subtype_indication] is name [signature]; entity Alias_1 is end; architecture Behave of Alias_1 is begin process variable Nmbr: BIT_VECTOR (31 downto 0); -- alias declarations to split Nmbr into 3 pieces : alias Sign : BIT is Nmbr(31); alias Mantissa : BIT_VECTOR (23 downto 0) is Nmbr (30 downto 7); alias Exponent : BIT_VECTOR ( 6 downto 0) is Nmbr ( 6 downto 0); begin wait; end process; end; -- the wait prevents an endless cycle ASICs... THE COURSE 10.9 Other Declarations 35 attribute_declaration ::= attribute identifier:type_name ; | attribute identifier:subtype_name ; entity Attribute_1 is end; architecture Behave of Attribute_1 is begin process type COORD is record X, Y : INTEGER; end record; attribute LOCATION : COORD; -- the attribute declaration begin wait ; -- the wait prevents an endless cycle end process; end; You define the attribute properties in an attribute specification: attribute LOCATION of adder1 : label is (10,15); positionOfComponent := adder1'LOCATION; 36 SECTION 10 VHDL ASICS... THE COURSE 10.9.4 Predefined Attributes Predefined attributes for signals Attribute Kind1 1 F=function, S=signal. Parameter T2 2Time T≥0 ns. The default, if T is not present, is T=0 ns. Result type3 3base(S)=base type of S. Result/restrictions S'DELAYED [(T)] S TIME base(S) S delayed by time T S'STABLE [(T)] S TIME BOOLEAN TRUE if no event on S for time T S'QUIET [(T)] S TIME BOOLEAN TRUE if S is quiet for time T S'TRANSACTION S BIT Toggles each cycle if S becomes active S'EVENT F BOOLEAN TRUE when event occurs on S S'ACTIVE F BOOLEAN TRUE if S is active S'LAST_EVENT F TIME Elapsed time since the last event on S S'LAST_ACTIVE F TIME Elapsed time since S was active S'LAST_VALUE F base(S) Previous value of S, before last event4 4VHDL-93 returns last value of each signal in array separately as an aggregate, VHDL-87 returns the last value of the composite signal. S'DRIVING F BOOLEAN TRUE if every element of S is driven5 5VHDL-93 only. S'DRIVING_VALUE F base(S) Value of the driver for S in the current process5 ASICs... THE COURSE 10.9 Other Declarations 37 Predefined attributes for scalar and array types Attribute Kind1 Prefix T, A, E2 Parame- ter X or N3 Result type4 Result T'BASE T any base(T) base(T), use only with other attribute T'LEFT V scalar T Left bound of T T'RIGHT V scalar T Right bound of T T'HIGH V scalar T Upper bound of T T'LOW V scalar T Lower bound of T T'ASCENDING V scalar BOOLEAN True if range of T is ascending5 T'IMAGE(X) F scalar base(T) STRING String representation of X in T4 T'VALUE(X) F scalar STRING base(T) Value in T with representation X4 T'POS(X) F discrete base(T) UI Position number of X in T (starts at 0) T'VAL(X) F discrete UI base(T) Value of position X in T T'SUCC(X) F discrete base(T) base(T) Value of position X in T plus one T'PRED(X) F discrete base(T) base(T) Value of position X in T minus one T'LEFTOF(X) F discrete base(T) base(T) Value to the left of X in T T'RIGHTOF(X) F discrete base(T) base(T) Value to the right of X in T A'LEFT[(N)] F array UI T(Result) Left bound of index N of array A A'RIGHT[(N)] F array UI T(Result) Right bound of index N of array A A'HIGH[(N)] F array UI T(Result) Upper bound of index N of array A A'LOW[(N)] F array UI T(Result) Lower bound of index N of array A A'RANGE[(N)] R array UI T(Result) Range A'LEFT(N) to A'RIGHT(N)6 A'REVERSE_RANGE[ (N)] R array UI T(Result) Opposite range to A'RANGE[(N)] A'LENGTH[(N)] V array UI UI Number of values in index N of array A A'ASCENDING[(N)] V array UI BOOLEAN True if index N of A is ascending4 E'SIMPLE_NAME V name STRING Simple name of E4 E'INSTANCE_NAME V name STRING Path includes instantiated entities4 E'PATH_NAME V name STRING Path excludes instantiated entities4 1T=Type, F=Function, V=Value, R=Range. 38 SECTION 10 VHDL ASICS... THE COURSE 2any=any type or subtype, scalar=scalar type or subtype, discrete=discrete or physical type or subtype, name=entity name=identifier, character literal, or operator symbol. 3base(T)=base type of T, T=type of T, UI= universal_integer,T(Result)=type of object described in result column. 4base(T)=base type of T, T=type of T, UI= universal_integer,T(Result)=type of object described in result column. 5Only available in VHDL-93. For 'ASCENDING all enumeration types are ascending. 6Or reverse for descending ranges. ASICs... THE COURSE 10.10 Sequential Statements 39 10.10 Sequential Statements sequential_statement ::= wait_statement | assertion_statement | signal_assignment_statement | variable_assignment_statement | procedure_call_statement | if_statement | case_statement | loop_statement | next_statement | exit_statement | return_statement | null_statement | report_statement 10.10.1 Wait Statement Key terms and concepts: suspending (stopping) a process or procedure ? sensitivity to events (changes) on static signals ? sensitivity clause contains sensitivity list after on ? process resumes at event on signal in the sensitivity set ? condition clause after until ? timeout (after for) wait on light makes you wait until a traffic light changes (any change) wait until light = green makes you wait (even at a green light) until the traffic signal changes to green if light = (red or yellow) then wait until light = green; end if; describes the basic rules at a traffic intersection wait_statement ::= [label:] wait [sensitivity_clause] [condition_clause] [timeout_clause] ; sensitivity_clause ::= on sensitivity_list sensitivity_list ::= signal_name { , signal_name } condition_clause ::= until condition condition ::= boolean_expression timeout_clause ::= for time_expression wait_statement ::= [label:] wait [on signal_name {, signal_name}] [until boolean_expression] [for time_expression] ; entity DFF is port (CLK, D : BIT; Q : out BIT); end; --1 architecture Behave of DFF is --2 40 SECTION 10 VHDL ASICS... THE COURSE process begin wait until Clk = '1'; Q <= D ; end process; --3 end; --4 entity Wait_1 is port (Clk, s1, s2 :in BIT); end; architecture Behave of Wait_1 is signal x : BIT_VECTOR (0 to 15); begin process variable v : BIT; begin wait; -- Wait forever, stops simulation. wait on s1 until s2 = '1'; -- Legal, but s1, s2 are signals so -- s1 is in sensitivity list, and s2 is not in the sensitivity set. -- Sensitivity set is s1 and process will not resume at event on s2. wait on s1, s2; -- resumes at event on signal s1 or s2. wait on s1 for 10 ns; -- resumes at event on s1 or after 10 ns. wait on x; -- resumes when any element of array x -- has an event. -- wait on x(1 to v); -- Illegal, nonstatic name, since v is a variable. end process; end; entity Wait_2 is port (Clk, s1, s2:in BIT); end; architecture Behave of Wait_2 is begin process variable v : BIT; begin wait on Clk; -- resumes when Clk has an event: rising or falling. wait until Clk = '1'; -- resumes on rising edge. wait on Clk until Clk = '1'; -- equivalent to the last statement. wait on Clk until v = '1'; -- The above is legal, but v is a variable so -- Clk is in sensitivity list, v is not in the sensitivity set. -- Sensitivity set is Clk and process will not resume at event on v. wait on Clk until s1 = '1'; -- The above is legal, but s1 is a signal so -- Clk is in sensitivity list, s1 is not in the sensitivity set. -- Sensitivity set is Clk, process will not resume at event on s1. end process; end; ASICs... THE COURSE 10.10 Sequential Statements 41 10.10.2 Assertion and Report Statements assertion_statement ::= [label:] assert boolean_expression [report expression] [severity expression] ; report_statement ::= [label:] report expression [severity expression] ; entity Assert_1 is port (I:INTEGER:=0); end; architecture Behave of Assert_1 is begin process begin assert (I > 0) report "I is negative or zero"; wait; end process; end; 10.10.3 Assignment Statements Key terms and concepts: A variable assignment statement updates immediately ? A signal assignment statement schedules a future assignment ? simulation cycle ? delta cycle ? delta time ? delta, δ ? event ? delay models: transport and inertial delay (the default) ? pulse rejection limit variable_assignment_statement ::= [label:] name|aggregate := expression ; entity Var_Assignment is end; architecture Behave of Var_Assignment is signal s1 : INTEGER := 0; begin process variable v1,v2 : INTEGER := 0; begin assert (v1/=0) report "v1 is 0" severity note ; -- this prints v1 := v1 + 1; -- after this statement v1 is 1 assert (v1=0) report "v1 isn't 0" severity note ; -- this prints v2 := v2 + s1; -- signal and variable types must match wait; end process; end; 42 SECTION 10 VHDL ASICS... THE COURSE signal_assignment_statement::= [label:] target <= [transport | [ reject time_expression ] inertial] waveform ; entity Sig_Assignment_1 is end; architecture Behave of Sig_Assignment_1 is signal s1,s2,s3 : INTEGER := 0; begin process variable v1 : INTEGER := 1; begin assert (s1 /= 0) report "s1 is 0" severity note ; -- this prints. s1 <= s1 + 1; -- after this statement s1 is still 0. assert (s1 /= 0) report "s1 still 0" severity note ; -- this prints. wait; end process; end; entity Sig_Assignment_2 is end; architecture Behave of Sig_Assignment_2 is signal s1, s2, s3 : INTEGER := 0; begin process variable v1 : INTEGER := 1; begin -- s1, s2, s3 are initially 0; now consider the following: s1 <= 1 ; -- schedules updates to s1 at end of 0 ns cycle. s2 <= s1; -- s2 is 0, not 1. wait for 1 ns; s3 <= s1; -- now s3 will be 1 at 1 ns. wait; end process; end; entity Transport_1 is end; architecture Behave of Transport_1 is signal s1, SLOW, FAST, WIRE : BIT := '0'; begin process begin s1 <= '1' after 1 ns, '0' after 2 ns, '1' after 3 ns ; -- schedules s1 to be '1' at t+1 ns, '0' at t+2 ns,'1' at t+3 ns wait; end process; -- inertial delay: SLOW rejects pulsewidths less than 5ns: process (s1) begin SLOW <= s1 after 5 ns ; end process; -- inertial delay: FAST rejects pulsewidths less than 0.5ns: process (s1) begin FAST <= s1 after 0.5 ns ; end process; -- transport delay: WIRE passes all pulsewidths... ASICs... THE COURSE 10.10 Sequential Statements 43 process (s1) begin WIRE <= transport s1 after 5 ns ; end process; end; process (s1) begin RJCT <= reject 2 ns s1 after 5 ns ; end process; 10.10.4 Procedure Call procedure_call_statement ::= [label:] procedure_name [(parameter_association_list)]; package And_Pkg is procedure V_And(a, b : BIT; signal c : out BIT); function V_And(a, b : BIT) return BIT; end; package body And_Pkg is procedure V_And(a, b : BIT; signal c: out BIT) is begin c <= a and b; end; function V_And(a, b: BIT) return BIT is begin return a and b; end; end And_Pkg; use work.And_Pkg.all; entity Proc_Call_1 is end; architecture Behave of Proc_Call_1 is signal A, B, Y: BIT := '0'; begin process begin V_And (A, B, Y); wait; end process; end; 10.10.5 If Statement if_statement ::= [if_label:] if boolean_expression then {sequential_statement} {elsif boolean_expression then {sequential_statement}} [else {sequential_statement}] end if [if_label]; entity If_Then_Else_1 is end; architecture Behave of If_Then_Else_1 is signal a, b, c: BIT :='1'; 44 SECTION 10 VHDL ASICS... THE COURSE begin process begin if c = '1' then c <= a ; else c <= b; end if; wait; end process; end; entity If_Then_1 is end; architecture Behave of If_Then_1 is signal A, B, Y : BIT :='1'; begin process begin if A = B then Y <= A; end if; wait; end process; end; 10.10.6 Case Statement case_statement ::= [case_label:] case expression is when choice {| choice} => {sequential_statement} {when choice {| choice} => {sequential_statement}} end case [case_label]; library IEEE; use IEEE.STD_LOGIC_1164.all; --1 entity sm_mealy is --2 port (reset, clock, i1, i2 : STD_LOGIC; o1, o2 : out STD_LOGIC); --3 end sm_mealy; --4 architecture Behave of sm_mealy is --5 type STATES is (s0, s1, s2, s3); signal current, new : STATES; --6 begin --7 synchronous : process (clock, reset) begin --8 if To_X01(reset) = '0' then current <= s0; --9 elsif rising_edge(clock) then current <= new; end if; --10 end process; --11 combinational : process (current, i1, i2) begin --12 case current is --13 when s0 => --14 if To_X01(i1) = '1' then o2 <='0'; o1 <='0'; new <= s2; --15 else o2 <= '1'; o1 <= '1'; new <= s1; end if; --16 when s1 => --17 if To_X01(i2) = '1' then o2 <='1'; o1 <='0'; new <= s1; --18 else o2 <='0'; o1 <='1'; new <= s3; end if; --19 when s2 => --20 if To_X01(i2) = '1' then o2 <='0'; o1 <='1'; new <= s2; --21 ASICs... THE COURSE 10.10 Sequential Statements 45 else o2 <= '1'; o1 <= '0'; new <= s0; end if; --22 when s3 => o2 <= '0'; o1 <= '0'; new <= s0; --23 when others => o2 <= '0'; o1 <= '0'; new <= s0; --24 end case; --25 end process; --26 end Behave; --27 46 SECTION 10 VHDL ASICS... THE COURSE 10.10.7 Other Sequential Control Statements loop_statement ::= [loop_label:] [while boolean_expression|for identifier in discrete_range] loop {sequential_statement} end loop [loop_label]; package And_Pkg is function V_And(a, b : BIT) return BIT; end; package body And_Pkg is function V_And(a, b : BIT) return BIT is begin return a and b; end; end And_Pkg; entity Loop_1 is port (x, y : in BIT := '1'; s : out BIT := '0'); end; use work.And_Pkg.all; architecture Behave of Loop_1 is begin loop s <= V_And(x, y); wait on x, y; end loop; end; The next statement [VHDL LRM8.10] forces completion of current loop iteration: next_statement ::= [label:] next [loop_label] [when boolean_expression]; An exit statement [VHDL LRM8.11] forces an exit from a loop. exit_statement ::= [label:] exit [loop_label] [when condition] ; ASICs... THE COURSE 10.10 Sequential Statements 47 loop wait on Clk; exit when Clk = '0'; end loop; -- equivalent to: wait until Clk = '0'; The return statement [VHDL LRM8.12] completes execution of a procedure or function: return_statement ::= [label:] return [expression]; A null statement [VHDL LRM8.13] does nothing: null_statement ::= [label:] null; 48 SECTION 10 VHDL ASICS... THE COURSE 10.11 Operators entity Operator_1 is end; architecture Behave of Operator_1 is --1 begin process --2 variable b : BOOLEAN; variable bt : BIT := '1'; variable i : INTEGER;--3 variable pi : REAL := 3.14; variable epsilon : REAL := 0.01; --4 variable bv4 : BIT_VECTOR (3 downto 0) := "0001"; --5 variable bv8 : BIT_VECTOR (0 to 7); --6 begin --7 b := "0000" < bv4; -- b is TRUE, "0000" treated as BIT_VECTOR. --8 b := 'f' > 'g'; -- b is FALSE, 'dictionary' comparison. --9 bt := '0' and bt; -- bt is '0', analyzer knows '0' is BIT. --10 bv4 := not bv4; -- bv4 is now "1110". --11 i := 1 + 2; -- Addition, must be compatible types. --12 i := 2 ** 3; -- Exponentiation, exponent must be integer. --13 i := 7/3; -- Division, L/R rounded towards zero, i=2. --14 i := 12 rem 7; -- Remainder, i=5. In general: --15 -- L rem R = L-((L/R)*R). --16 i := 12 mod 7; -- modulus, i=5. In general: --17 -- L mod R = L-(R*N) for an integer N. --18 -- shift := sll | srl | sla | sra | rol | ror (VHDL-93 only) --19 bv4 := "1001" srl 2; -- Shift right logical, now bv4="0100". --20 -- Logical shift fills with T'LEFT. --21 bv4 := "1001" sra 2; -- Shift right arithmetic, now bv4="0111". --22 -- Arithmetic shift fills with element at end being vacated. --23 bv4 := "1001" ror 2; -- Rotate right, now bv4="0110". --24 -- Rotate wraps around. --25 -- Integer argument to any shift operator may be negative or zero.--26 VHDL predefined operators (listed by increasing order of precedence) logical_operator ::= and | or | nand | nor | xor | xnor relational_operator ::= = | /= | < | <= | > | >= shift_operator::= sll | srl | sla | sra | rol | ror adding_operator ::= + | – | & sign ::= + | – multiplying_operator ::= * | / | mod | rem miscellaneous_operator ::= ** | abs | not ASICs... THE COURSE 10.12 Arithmetic 49 if (pi*2.718)/2.718 = 3.14 then wait; end if; -- This is unreliable.--27 if (abs(((pi*2.718)/2.718)-3.14)<epsilon) then wait; end if; -- Better. --28 bv8 := bv8(1 to 7) & bv8(0); -- Concatenation, a left rotation. --29 wait; end process; --30 end; --31 10.12 Arithmetic Key terms and concepts: type checking ? range checking ? type conversion between closely related types ? type_mark(expression)? type qualification and disambiguation (to persuade the analyzer) ? type_mark'(expression) entity Arithmetic_1 is end; architecture Behave of Arithmetic_1 is --1 begin process variable i : INTEGER := 1; variable r : REAL := 3.33; --2 variable b : BIT := '1'; --3 variable bv4 : BIT_VECTOR (3 downto 0) := "0001"; --4 variable bv8 : BIT_VECTOR (7 downto 0) := B"1000_0000"; --5 begin --6 -- i := r; -- you can't assign REAL to INTEGER. --7 -- bv4 := bv4 + 2; -- you can't add BIT_VECTOR and INTEGER. --8 -- bv4 := '1'; -- you can't assign BIT to BIT_VECTOR. --9 -- bv8 := bv4; -- an error, the arrays are different sizes. --10 r := REAL(i); -- OK, uses a type conversion. --11 i := INTEGER(r); -- OK (0.5 rounds up or down). --12 bv4 := "001" & '1'; -- OK, you can mix an array and a scalar. --13 bv8 := "0001" & bv4; -- OK, if arguments are correct lengths. --14 wait; end process; end; --15 entity Arithmetic_2 is end; architecture Behave of Arithmetic_2 is --1 type TC is range 0 to 100; -- Type INTEGER. --2 type TF is range 32 to 212; -- Type INTEGER. --3 subtype STC is INTEGER range 0 to 100; -- Subtype of type INTEGER. --4 subtype STF is INTEGER range 32 to 212; -- Base type is INTEGER. --5 begin process --6 variable t1 : TC := 25; variable t2 : TF := 32; --7 variable st1 : STC := 25; variable st2 : STF := 32; --8 begin --9 -- t1 := t2; -- Illegal, different types. --10 -- t1 := st1; -- Illegal, different types and subtypes. --11 50 SECTION 10 VHDL ASICS... THE COURSE st2 := st1; -- OK to use same base types. --12 st2 := st1 + 1; -- OK to use subtype and base type. --13 -- st2 := 213; -- Error, outside range at analysis time. --14 -- st2 := 212 + 1; -- Error, outside range at analysis time. --15 st1 := st1 + 100; -- Error, outside range at initialization. --16 wait; end process; end; entity Arithmetic_3 is end; architecture Behave of Arithmetic_3 is --1 type TYPE_1 is array (INTEGER range 3 downto 0) of BIT; --2 type TYPE_2 is array (INTEGER range 3 downto 0) of BIT; --3 subtype SUBTYPE_1 is BIT_VECTOR (3 downto 0); --4 subtype SUBTYPE_2 is BIT_VECTOR (3 downto 0); --5 begin process --6 variable bv4 : BIT_VECTOR (3 downto 0) := "0001"; --7 variable st1 : SUBTYPE_1 := "0001"; variable t1 : TYPE_1 := "0001"; --8 variable st2 : SUBTYPE_2 := "0001"; variable t2 : TYPE_2 := "0001"; --9 begin --10 bv4 := st1; -- OK, compatible type and subtype. --11 -- bv4 := t1; -- Illegal, different types. --12 bv4 := BIT_VECTOR(t1); -- OK, type conversion. --13 st1 := bv4; -- OK, compatible subtype & base type. --14 -- st1 := t1; -- Illegal, different types. --15 st1 := SUBTYPE_1(t1); -- OK, type conversion. --16 -- t1 := st1; -- Illegal, different types. --17 -- t1 := bv4; -- Illegal, different types. --18 t1 := TYPE_1(bv4); -- OK, type conversion. --19 -- t1 := t2; -- Illegal, different types. --20 t1 := TYPE_1(t2); -- OK, type conversion. --21 st1 := st2; -- OK, compatible subtypes. --22 wait; end process; end; --23 10.12.1 IEEE Synthesis Packages package Part_NUMERIC_BIT is type UNSIGNED is array (NATURAL range <> ) of BIT; type SIGNED is array (NATURAL range <> ) of BIT; function "+" (L, R : UNSIGNED) return UNSIGNED; -- other function definitions that overload +, -, = , >, and so on. end Part_NUMERIC_BIT; package body Part_NUMERIC_BIT is constant NAU : UNSIGNED(0 downto 1) := (others =>'0'); -- Null array. ASICs... THE COURSE 10.12 Arithmetic 51 constant NAS : SIGNED(0 downto 1):=(others => '0'); -- Null array. constant NO_WARNING : BOOLEAN := FALSE; -- Default to emit warnings. function MAX (LEFT, RIGHT : INTEGER) return INTEGER is begin -- Internal function used to find longest of two inputs. if LEFT > RIGHT then return LEFT; else return RIGHT; end if; end MAX; function ADD_UNSIGNED (L, R : UNSIGNED; C: BIT) return UNSIGNED is constant L_LEFT : INTEGER := L'LENGTH-1; -- L, R must be same length. alias XL : UNSIGNED(L_LEFT downto 0) is L; -- Descending alias, alias XR : UNSIGNED(L_LEFT downto 0) is R; -- aligns left ends. variable RESULT : UNSIGNED(L_LEFT downto 0); variable CBIT : BIT := C; begin for I in 0 to L_LEFT loop -- Descending alias allows loop. RESULT(I) := CBIT xor XL(I) xor XR(I); -- CBIT = carry, initially = C. CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I)); end loop; return RESULT; end ADD_UNSIGNED; function RESIZE (ARG : UNSIGNED; NEW_SIZE : NATURAL) return UNSIGNED is constant ARG_LEFT : INTEGER := ARG'LENGTH-1; alias XARG : UNSIGNED(ARG_LEFT downto 0) is ARG; -- Descending range. variable RESULT : UNSIGNED(NEW_SIZE-1 downto 0) := (others => '0'); begin -- resize the input ARG to length NEW_SIZE if (NEW_SIZE < 1) then return NAU; end if; -- Return null array. if XARG'LENGTH = 0 then return RESULT; end if; -- Null to empty. if (RESULT'LENGTH < ARG'LENGTH) then -- Check lengths. RESULT(RESULT'LEFT downto 0) := XARG(RESULT'LEFT downto 0); else -- Need to pad the result with some '0's. RESULT(RESULT'LEFT downto XARG'LEFT + 1) := (others => '0'); RESULT(XARG'LEFT downto 0) := XARG; end if; return RESULT; end RESIZE; function "+" (L, R : UNSIGNED) return UNSIGNED is -- Overloaded '+'. constant SIZE : NATURAL := MAX(L'LENGTH, R'LENGTH); begin -- If length of L or R < 1 return a null array. if ((L'LENGTH < 1) or (R'LENGTH < 1)) then return NAU; end if; return ADD_UNSIGNED(RESIZE(L, SIZE), RESIZE(R, SIZE), '0'); end "+"; end Part_NUMERIC_BIT; 52 SECTION 10 VHDL ASICS... THE COURSE function TO_INTEGER (ARG : UNSIGNED) return NATURAL; function TO_INTEGER (ARG : SIGNED) return INTEGER; function TO_UNSIGNED (ARG, SIZE : NATURAL) return UNSIGNED; function TO_SIGNED (ARG : INTEGER; SIZE : NATURAL) return SIGNED; function RESIZE (ARG : SIGNED; NEW_SIZE : NATURAL) return SIGNED; function RESIZE (ARG : UNSIGNED; NEW_SIZE : NATURAL) return UNSIGNED; -- set XMAP to convert unknown values, default is 'X'->'0' function TO_01(S : UNSIGNED; XMAP : STD_LOGIC := '0') return UNSIGNED; function TO_01(S : SIGNED; XMAP : STD_LOGIC := '0') return SIGNED; library IEEE; use IEEE.STD_LOGIC_1164.all; package Part_NUMERIC_STD is type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC; end Part_NUMERIC_STD; -- function STD_MATCH (L, R: T) return BOOLEAN; -- T = STD_ULOGIC UNSIGNED SIGNED STD_LOGIC_VECTOR STD_ULOGIC_VECTOR type BOOLEAN_TABLE is array(STD_ULOGIC, STD_ULOGIC) of BOOLEAN; constant MATCH_TABLE : BOOLEAN_TABLE := ( --------------------------------------------------------------------- -- U X 0 1 Z W L H - --------------------------------------------------------------------- (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE), -- | U | (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE), -- | X | (FALSE,FALSE, TRUE,FALSE,FALSE,FALSE, TRUE,FALSE, TRUE), -- | 0 | (FALSE,FALSE,FALSE, TRUE,FALSE,FALSE,FALSE, TRUE, TRUE), -- | 1 | (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE), -- | Z | (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE), -- | W | (FALSE,FALSE, TRUE,FALSE,FALSE,FALSE, TRUE,FALSE, TRUE), -- | L | (FALSE,FALSE,FALSE, TRUE,FALSE,FALSE,FALSE, TRUE, TRUE), -- | H | ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE));-- | - | IM_TRUE = STD_MATCH(STD_LOGIC_VECTOR ("10HLXWZ-"), STD_LOGIC_VECTOR ("HL10----")) -- is TRUE entity Counter_1 is end; --1 library STD; use STD.TEXTIO.all; --2 ASICs... THE COURSE 10.12 Arithmetic 53 library IEEE; use IEEE.STD_LOGIC_1164.all; --3 use work.NUMERIC_STD.all; --4 architecture Behave_2 of Counter_1 is --5 signal Clock : STD_LOGIC := '0'; --6 signal Count : UNSIGNED (2 downto 0) := "000"; --7 begin --8 process begin --9 wait for 10 ns; Clock <= not Clock; --10 if (now > 340 ns) then wait; --11 end if; --12 end process; --13 process begin --14 wait until (Clock = '0'); --15 if (Count = 7) --16 then Count <= "000"; --17 else Count <= Count + 1; --18 end if; --19 end process; --20 process (Count) variable L: LINE; begin write(L, now); --21 write(L, STRING'(" Count=")); write(L, TO_INTEGER(Count)); --22 writeline(output, L); --23 end process; --24 end; --25 54 SECTION 10 VHDL ASICS... THE COURSE 10.13 Concurrent Statements concurrent_statement ::= block_statement | process_statement | [ label : ] [ postponed ] procedure_call ; | [ label : ] [ postponed ] assertion ; | [ label : ] [ postponed ] conditional_signal_assignment | [ label : ] [ postponed ] selected_signal_assignment | component_instantiation_statement | generate_statement 10.13.1 Block Statement Key terms and concepts: guard expression ? GUARD ? guarded signals (register and bus) ? driver ? disconnected ? disconnect statement block_statement ::= block_label: block [(guard_expression)] [is] [generic (generic_interface_list); [generic map (generic_association_list);]] [port (port_interface_list); [port map (port_association_list);]] {block_declarative_item} begin {concurrent_statement} end block [block_label] ; library ieee; use ieee.std_logic_1164.all; entity bus_drivers is end; architecture Structure_1 of bus_drivers is signal TSTATE: STD_LOGIC bus; signal A, B, OEA, OEB : STD_LOGIC:= '0'; begin process begin OEA <= '1' after 100 ns, '0' after 200 ns; OEB <= '1' after 300 ns; wait; end process; B1 : block (OEA = '1') disconnect all : STD_LOGIC after 5 ns; -- Only needed for float time. ASICs... THE COURSE 10.13 Concurrent Statements 55 begin TSTATE <= guarded not A after 3 ns; end block; B2 : block (OEB = '1') disconnect all : STD_LOGIC after 5 ns; -- Float time = 5 ns. begin TSTATE <= guarded not B after 3 ns; end block; end; architecture Structure_2 of bus_drivers is signal TSTATE : STD_LOGIC; signal A, B, OEA, OEB : STD_LOGIC := '0'; begin process begin OEA <= '1' after 100 ns, '0' after 200 ns; OEB <= '1' after 300 ns; wait; end process; process(OEA, OEB, A, B) begin if (OEA = '1') then TSTATE <= not A after 3 ns; elsif (OEB = '1') then TSTATE <= not B after 3 ns; else TSTATE <= 'Z' after 5 ns; end if; end process; end; 10.13.2 Process Statement Key terms and concepts: process sensitivity set ? process execution occurs during a simulation cycle—made up of delta cycles process_statement ::= [process_label:] [postponed] process [(signal_name {, signal_name})] [is] {subprogram_declaration | subprogram_body | type_declaration | subtype_declaration | constant_declaration | variable_declaration | file_declaration | alias_declaration | attribute_declaration | attribute_specification | use_clause | group_declaration | group_template_declaration} begin {sequential_statement} end [postponed] process [process_label]; 56 SECTION 10 VHDL ASICS... THE COURSE entity Mux_1 is port (i0, i1, sel : in BIT := '0'; y : out BIT); end; architecture Behave of Mux_1 is begin process (i0, i1, sel) begin -- i0, i1, sel = sensitivity set case sel is when '0' => y <= i0; when '1' => y <= i1; end case; end process; end; entity And_1 is port (a, b : in BIT := '0'; y : out BIT); end; architecture Behave of And_1 is begin process (a, b) begin y <= a and b; end process; end; entity FF_1 is port (clk, d: in BIT := '0'; q : out BIT); end; architecture Behave of FF_1 is begin process (clk) begin if clk'EVENT and clk = '1' then q <= d; end if; end process; end; entity FF_2 is port (clk, d: in BIT := '0'; q : out BIT); end; architecture Behave of FF_2 is begin process begin -- The equivalent process has a wait at the end: if clk'event and clk = '1' then q <= d; end if; wait on clk; end process; end; entity FF_3 is port (clk, d: in BIT := '0'; q : out BIT); end; architecture Behave of FF_3 is begin process begin -- No sensitivity set with a wait statement. wait until clk = '1'; q <= d; end process; end; 10.13.3 Concurrent Procedure Call package And_Pkg is procedure V_And(a,b:BIT; signal c:out BIT); end; package body And_Pkg is procedure V_And(a,b:BIT; signal c:out BIT) is begin c <= a and b; end; end And_Pkg; use work.And_Pkg.all; entity Proc_Call_2 is end; architecture Behave of Proc_Call_2 is signal A, B, Y : BIT := '0'; ASICs... THE COURSE 10.13 Concurrent Statements 57 begin V_And (A, B, Y); -- Concurrent procedure call. process begin wait; end process; -- Extra process to stop. end; 10.13.4 Concurrent Signal Assignment Key terms and concepts: There are two forms of concurrent signal assignment statement: A selected signal assignment statement is equivalent to a case statement inside a processstatement [VHDL LRM9.5.2]. A conditional signal assignment statement is, in its most general form, equivalent to an if statement inside a processstatement [VHDL LRM9.5.1]. selected_signal_assignment ::= with expression select name|aggregate <= [guarded] [transport|[reject time_expression] inertial] waveform when choice {| choice} {, waveform when choice {| choice} } ; entity Selected_1 is end; architecture Behave of Selected_1 is signal y,i1,i2 : INTEGER; signal sel : INTEGER range 0 to 1; begin with sel select y <= i1 when 0, i2 when 1; end; entity Selected_2 is end; architecture Behave of Selected_2 is signal i1,i2,y : INTEGER; signal sel : INTEGER range 0 to 1; begin process begin case sel is when 0 => y <= i1; when 1 => y <= i2; end case; wait on i1, i2; end process; end; conditional_signal_assignment ::= name|aggregate <= [guarded] [transport|[reject time_expression] inertial] {waveform when boolean_expression else} waveform [when boolean_expression]; 58 SECTION 10 VHDL ASICS... THE COURSE entity Conditional_1 is end; architecture Behave of Conditional_1 is signal y,i,j : INTEGER; signal clk : BIT; begin y <= i when clk = '1' else j; -- conditional signal assignment end; entity Conditional_2 is end; architecture Behave of Conditional_2 is signal y,i : INTEGER; signal clk : BIT; begin process begin if clk = '1' then y <= i; else y <= y ; end if; wait on clk; end process; end; A concurrent signal assignment statement can look like a sequential signal assignment statement: entity Assign_1 is end; architecture Behave of Assign_1 is signal Target, Source : INTEGER; begin Target <= Source after 1 ns; -- looks like signal assignment end; Here is the equivalent process: entity Assign_2 is end; architecture Behave of Assign_2 is signal Target, Source : INTEGER; begin process begin Target <= Source after 1 ns; wait on Source; end process; end; entity Assign_3 is end; architecture Behave of Assign_3 is signal Target, Source : INTEGER; begin process begin wait on Source; Target <= Source after 1 ns; end process; end; 10.13.5 Concurrent Assertion Statement A concurrent assertion statement is equivalent to a passive processstatement (without a sensitivity list) that contains an assertionstatement followed by a wait statement. ASICs... THE COURSE 10.13 Concurrent Statements 59 concurrent_assertion_statement ::= [ label : ] [ postponed ] assertion ; If the assertion condition contains a signal, then the equivalent processstatement will include a final wait statement with a sensitivity clause. A concurrent assertion statement with a condition that is static expression is equivalent to a processstatement that ends in a wait statement that has no sensitivity clause. The equivalent process will execute once, at the beginning of simulation, and then wait indefinitely. 10.13.6 Component Instantiation component_instantiation_statement ::= instantiation_label: [component] component_name |entity entity_name [(architecture_identifier)] |configuration configuration_name [generic map (generic_association_list)] [port map (port_association_list)] ; entity And_2 is port (i1, i2 : in BIT; y : out BIT); end; architecture Behave of And_2 is begin y <= i1 and i2; end; entity Xor_2 is port (i1, i2 : in BIT; y : out BIT); end; architecture Behave of Xor_2 is begin y <= i1 xor i2; end; entity Half_Adder_2 is port (a,b : BIT := '0'; sum, cry : out BIT); end; architecture Netlist_2 of Half_Adder_2 is use work.all; -- need this to see the entities Xor_2 and And_2 begin X1 : entity Xor_2(Behave) port map (a, b, sum); -- VHDL-93 only A1 : entity And_2(Behave) port map (a, b, cry); -- VHDL-93 only end; 60 SECTION 10 VHDL ASICS... THE COURSE 10.13.7 Generate Statement generate_statement ::= generate_label: for generate_parameter_specification |if boolean_expression generate [{block_declarative_item} begin] {concurrent_statement} end generate [generate_label] ; entity Full_Adder is port (X, Y, Cin : BIT; Cout, Sum: out BIT); end; architecture Behave of Full_Adder is begin Sum <= X xor Y xor Cin; Cout <= (X and Y) or (X and Cin) or (Y and Cin); end; entity Adder_1 is port (A, B : in BIT_VECTOR (7 downto 0) := (others => '0'); Cin : in BIT := '0'; Sum : out BIT_VECTOR (7 downto 0); Cout : out BIT); end; architecture Structure of Adder_1 is use work.all; component Full_Adder port (X, Y, Cin: BIT; Cout, Sum: out BIT); end component; signal C : BIT_VECTOR(7 downto 0); begin AllBits : for i in 7 downto 0 generate LowBit : if i = 0 generate FA : Full_Adder port map (A(0), B(0), Cin, C(0), Sum(0)); end generate; OtherBits : if i /= 0 generate FA : Full_Adder port map (A(i), B(i), C(i-1), C(i), Sum(i)); end generate; end generate; Cout <= C(7); end; For i=6, FA'INSTANCE_NAMEis :adder_1(structure):allbits(6):otherbits:fa: ASICs... THE COURSE 10.14 Execution 61 10.14 Execution Key terms and concepts: sequential execution ? concurrent execution ? difference between update for signals and variables entity Sequential_1 is end; architecture Behave of Sequential_1 is signal s1, s2 : INTEGER := 0; begin process begin s1 <= 1; -- sequential signal assignment 1 s2 <= s1 + 1; -- sequential signal assignment 2 wait on s1, s2 ; Variables and signals in VHDL Variables Signals entity Execute_1 is end; architecture Behave of Execute_1 is begin process variable v1 : INTEGER := 1; variable v2 : INTEGER := 2; begin v1 := v2; -- before: v1 = 1, v2 = 2 v2 := v1; -- after: v1 = 2, v2 = 2 wait; end process; end; entity Execute_2 is end; architecture Behave of Execute_2 is signal s1 : INTEGER := 1; signal s2 : INTEGER := 2; begin process begin s1 <= s2; -- before: s1 = 1, s2 = 2 s2 <= s1; -- after: s1 = 2, s2 = 1 wait; end process; end; Concurrent and sequential statements in VHDL Concurrent [VHDL LRM9] Sequential [VHDL LRM8] block process concurrent_procedure_call concurrent_assertion concurrent_signal_assignment component_instantiation generate wait assertion signal_assignment variable_assignment procedure_call if case loop next exit return null 62 SECTION 10 VHDL ASICS... THE COURSE end process; end; entity Concurrent_1 is end; architecture Behave of Concurrent_1 is signal s1, s2 : INTEGER := 0; begin L1 : s1 <= 1; -- concurrent signal assignment 1 L2 : s2 <= s1 + 1; -- concurrent signal assignment 2 end; entity Concurrent_2 is end; architecture Behave of Concurrent_2 is signal s1, s2 : INTEGER := 0; begin P1 : process begin s1 <= 1; wait on s2 ; end process; P2 : process begin s2 <= s1 + 1; wait on s1 ; end process; end; ASICs... THE COURSE 10.15 Configurations and Specifications 63 10.15 Configurations and Specifications Key terms and concepts: A configuration declaration defines a configuration—it is a library unit and is one of the basic units of VHDL code. A block configuration defines the configuration of a block statement or a design entity. A block configuration appears inside a configuration declaration, a component configuration, or nested in another block configuration. A configuration specification may appear in the declarative region of a generate statement, block statement, or architecture body. A component declaration may appear in the declarative region of a generate statement, block statement, architecture body, or package. A component configuration defines the configuration of a component and appears in a block 64 SECTION 10 VHDL ASICS... THE COURSE configuration. VHDL binding examples entity AD2 is port (A1, A2: in BIT; Y: out BIT); end; architecture B of AD2 is begin Y <= A1 and A2; end; entity XR2 is port (X1, X2: in BIT; Y: out BIT); end; architecture B of XR2 is begin Y <= X1 xor X2; end; component declaration configuration specification entity Half_Adder is port (X, Y: BIT; Sum, Cout: out BIT); end; architecture Netlist of Half_Adder is use work.all; component MX port (A, B: BIT; Z :out BIT);end component; component MA port (A, B: BIT; Z :out BIT);end component; for G1:MX use entity XR2(B) port map(X1 => A,X2 => B,Y => Z); begin G1:MX port map(X, Y, Sum); G2:MA port map(X, Y, Cout); end; configuration declaration block configuration component configuration configuration C1 of Half_Adder is use work.all; for Netlist for G2:MA use entity AD2(B) port map(A1 => A,A2 => B,Y => Z); end for; end for; end; ASICs... THE COURSE 10.15 Configurations and Specifications 65 VHDL binding configuration declaration configuration identifier of entity_name is {use_clause|attribute_specification|group_declaration} block_configuration end [configuration] [configuration_identifier]; block configuration for architecture_name |block_statement_label |generate_statement_label [(index_specification)] {use selected_name {, selected_name};} {block_configuration|component_configuration} end for ; configuration specification for instantiation_label{,instantiation_label}:component_name |others:component_name |all:component_name [use entity entity_name [(architecture_identifier)] |configuration configuration_name |open] [generic map (generic_association_list)] [port map (port_association_list)]; component declaration component identifier [is] [generic (local_generic_interface_list);] [port (local_port_interface_list);] end component [component_identifier]; component configuration for instantiation_label {, instantiation_label}:component_name |others:component_name |all:component_name [[use entity entity_name [(architecture_identifier)] |configuration configuration_name |open] [generic map (generic_association_list)] [port map (port_association_list)];] [block_configuration] end for; 66 SECTION 10 VHDL ASICS... THE COURSE 10.16 An Engine Controller A temperature converter library IEEE; use IEEE.STD_LOGIC_1164.all; -- type STD_LOGIC, rising_edge use IEEE.NUMERIC_STD.all ; -- type UNSIGNED, "+", "/" entity tconv is generic TPD : TIME:= 1 ns; port (T_in : in UNSIGNED(11 downto 0); clk, rst : in STD_LOGIC; T_out : out UNSIGNED(11 downto 0)); end; architecture rtl of tconv is signal T : UNSIGNED(7 downto 0); constant T2 : UNSIGNED(1 downto 0) := "10" ; constant T4 : UNSIGNED(2 downto 0) := "100" ; constant T32 : UNSIGNED(5 downto 0) := "100000" ; begin process(T) begin T_out <= T + T/T2 + T/T4 + T32 after TPD; end process; end rtl; T_in = temperature in °C T_out = temperature in °F The conversion formula from Centigrade to Fahren- heit is: T(°F) = (9/5)×T(°C)+ 32 This converter uses the approximation: 9/5 ≈1.75=1+0.5+0.25 ASICs... THE COURSE 10.16 An Engine Controller 67 A digital filter library IEEE; use IEEE.STD_LOGIC_1164.all; -- STD_LOGIC type, rising_edge use IEEE.NUMERIC_STD.all; -- UNSIGNED type, "+" and "/" entity filter is generic TPD : TIME := 1 ns; port (T_in : in UNSIGNED(11 downto 0); rst, clk : in STD_LOGIC; T_out: out UNSIGNED(11 downto 0)); end; architecture rtl of filter is type arr is array (0 to 3) of UNSIGNED(11 downto 0); signal i : arr ; constant T4 : UNSIGNED(2 downto 0) := "100"; begin process(rst, clk) begin if (rst = '1') then for n in 0 to 3 loop i(n) <= (others =>'0') after TPD; end loop; else if(rising_edge(clk)) then i(0) <= T_in after TPD;i(1) <= i(0) after TPD; i(2) <= i(1) after TPD;i(3) <= i(2) after TPD; end if; end if; end process; process(i) begin T_out <= ( i(0) + i(1) + i(2) + i(3) )/T4 after TPD; end process; end rtl; The filter computes a mov- ing average over four suc- cessive samples in time. Notice i(0) i(1) i(2) i(3) are each 12 bits wide. Then the sum i(0) + i(1) + i(2) + i(3) is 14 bits wide, and the average ( i(0) + i(1) + i(2) + i(3) )/T4 is 12 bits wide. All delays are generic TPD. 68 SECTION 10 VHDL ASICS... THE COURSE The input register library IEEE; use IEEE.STD_LOGIC_1164.all; -- type STD_LOGIC, rising_edge use IEEE.NUMERIC_STD.all ; -- type UNSIGNED entity register_in is generic ( TPD : TIME := 1 ns); port (T_in : in UNSIGNED(11 downto 0); clk, rst : in STD_LOGIC; T_out : out UNSIGNED(11 downto 0)); end; architecture rtl of register_in is begin process(clk, rst) begin if (rst = '1') then T_out <= (others => '0') after TPD; else if (rising_edge(clk)) then T_out <= T_in after TPD; end if; end if; end process; end rtl ; 12-bit-wide register for the temperature input signals. If the input is asynchro- nous (from an A/D converter with a sepa- rate clock, for example), we would need to worry about metastability. All delays are generic TPD. ASICs... THE COURSE 10.16 An Engine Controller 69 A first-in, first-out stack (FIFO) library IEEE; use IEEE.NUMERIC_STD.all ; -- UNSIGNED type use ieee.std_logic_1164.all; -- STD_LOGIC type, rising_edge entity fifo is generic (width : INTEGER := 12; depth : INTEGER := 16); port (clk, rst, push, pop : STD_LOGIC; Di : in UNSIGNED (width-1 downto 0); Do : out UNSIGNED (width-1 downto 0); empty, full : out STD_LOGIC); end fifo; architecture rtl of fifo is subtype ptype is INTEGER range 0 to (depth-1); signal diff, Ai, Ao : ptype; signal f, e : STD_LOGIC; type a is array (ptype) of UNSIGNED(width-1 downto 0); signal mem : a ; function bump(signal ptr : INTEGER range 0 to (depth-1)) return INTEGER is begin if (ptr = (depth-1)) then return 0; else return (ptr + 1); end if; end; begin process(f,e) begin full <= f ; empty <= e; end process; process(diff) begin if (diff = depth -1) then f <= '1'; else f <= '0'; end if; if (diff = 0) then e <= '1'; else e <= '0'; end if; end process; process(clk, Ai, Ao, Di, mem, push, pop, e, f) begin if(rising_edge(clk)) then if(push='0')and(pop='1')and(e = '0') then Do <= mem(Ao); end if; if(push='1')and(pop='0')and(f = '0') then mem(Ai) <= Di; end if; end if ; end process; process(rst, clk) begin if(rst = '1') then Ai <= 0; Ao <= 0; diff <= 0; else if(rising_edge(clk)) then if (push = '1') and (f = '0') and (pop = '0') then Ai <= bump(Ai); diff <= diff + 1; elsif (pop = '1') and (e = '0') and (push = '0') then Ao <= bump(Ao); diff <= diff - 1; end if; end if; end if; end process; end; FIFO (first-in, first-out) register Reads (pop = 1) and writes (push = 1) are synchronous to the ris- ing edge of the clock. Read and write should not occur at the same time. The width (num- ber of bits in each word) and depth (num- ber of words) are generics. External signals: clk, clock rst, reset active-high push, write to FIFO pop, read from FIFO Di, data in Do, data out empty, FIFO flag full, FIFO flag Internal signals: diff, difference pointer Ai, input address Ao, output address f, full flag e, empty flag No delays in this model. 70 SECTION 10 VHDL ASICS... THE COURSE A FIFO controller library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.NUMERIC_STD.all; entity fifo_control is generic TPD : TIME := 1 ns; port(D_1, D_2 : in UNSIGNED(11 downto 0); sel : in UNSIGNED(1 downto 0) ; read , f1, f2, e1, e2 : in STD_LOGIC; r1, r2, w12 : out STD_LOGIC; D : out UNSIGNED(11 downto 0)) ; end; architecture rtl of fifo_control is begin process (read, sel, D_1, D_2, f1, f2, e1, e2) begin r1 <= '0' after TPD; r2 <= '0' after TPD; if (read = '1') then w12 <= '0' after TPD; case sel is when "01" => D <= D_1 after TPD; r1 <= '1' after TPD; when "10" => D <= D_2 after TPD; r2 <= '1' after TPD; when "00" => D(3) <= f1 after TPD; D(2) <= f2 after TPD; D(1) <= e1 after TPD; D(0) <= e2 after TPD; when others => D <= "ZZZZZZZZZZZZ" after TPD; end case; elsif (read = '0') then D <= "ZZZZZZZZZZZZ" after TPD; w12 <= '1' after TPD; else D <= "ZZZZZZZZZZZZ" after TPD; end if; end process; end rtl; This handles the read- ing and writing to the FIFOs under control of the processor (mpu). The mpu can ask for data from either FIFO or for status flags to be placed on the bus. Inputs: D_1 data in from FIFO1 D_2 data in from FIFO2 sel FIFO select from mpu read FIFO read from mpu f1,f2,e1,e2 flags from FIFOs Outputs: r1, r2 read enables for FIFOs w12 write enable for FIFOs D data out to mpu bus ASICs... THE COURSE 10.16 An Engine Controller 71 package TC_Components is component register_in generic (TPD : TIME := 1 ns); port (T_in : in UNSIGNED(11 downto 0); clk, rst : in STD_LOGIC; T_out : out UNSIGNED(11 downto 0)); end component; component tconv generic (TPD : TIME := 1 ns); port (T_in : in UNSIGNED (7 downto 0); clk, rst : in STD_LOGIC; T_out : out UNSIGNED(7 downto 0)); end component; component filter generic (TPD : TIME := 1 ns); port (T_in : in UNSIGNED (7 downto 0); rst, clk : in STD_LOGIC; T_out : out UNSIGNED(7 downto 0)); end component; Top level of temperature controller library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity T_Control is port (T_in1, T_in2 : in UNSIGNED (11 downto 0); sensor: in UNSIGNED(1 downto 0); clk, RD, rst : in STD_LOGIC; D : out UNSIGNED(11 downto 0)); end; architecture structure of T_Control is use work.TC_Components.all; signal F, E : UNSIGNED (2 downto 1); signal T_out1, T_out2, R_out1, R_out2, F1, F2, FIFO1, FIFO2 : UNSIGNED(11 downto 0); signal RD1, RD2, WR: STD_LOGIC ; begin RG1 : register_in generic map (1ns) port map (T_in1,clk,rst,R_out1); RG2 : register_in generic map (1ns) port map (T_in2,clk,rst,R_out2); TC1 : tconv generic map (1ns) port map (R_out1, T_out1); TC2 : tconv generic map (1ns) port map (R_out2, T_out2); TF1 : filter generic map (1ns) port map (T_out1, rst, clk, F1); TF2 : filter generic map (1ns) port map (T_out2, rst, clk, F2); FI1 : fifo generic map (12,16) port map (clk, rst, WR, RD1, F1, FIFO1, E(1), F(1)); FI2 : fifo generic map (12,16) port map (clk, rst, WR, RD2, F2, FIFO2, E(2), F(2)); FC1 : fifo_control port map (FIFO1, FIFO2, sensor, RD, F(1), F(2), E(1), E(2), RD1, RD2, WR, D); end structure; 72 SECTION 10 VHDL ASICS... THE COURSE component fifo generic (width:INTEGER := 12; depth : INTEGER := 16); port (clk, rst, push, pop : STD_LOGIC; Di : UNSIGNED (width-1 downto 0); Do : out UNSIGNED (width-1 downto 0); empty, full : out STD_LOGIC); end component; component fifo_control generic (TPD:TIME := 1 ns); port (D_1, D_2 : in UNSIGNED(7 downto 0); select : in UNSIGNED(1 downto 0); read, f1, f2, e1, e2 : in STD_LOGIC; r1, r2, w12 : out STD_LOGIC; D : out UNSIGNED(7 downto 0)) ; end component; end; library IEEE; use IEEE.std_logic_1164.all; -- type STD_LOGIC use IEEE.numeric_std.all; -- type UNSIGNED entity test_TC is end; architecture testbench of test_TC is component T_Control port (T_1, T_2 : in UNSIGNED(11 downto 0); clk : in STD_LOGIC; sensor: in UNSIGNED( 1 downto 0) ; read : in STD_LOGIC; rst : in STD_LOGIC; D : out UNSIGNED(7 downto 0)); end component; signal T_1, T_2 : UNSIGNED(11 downto 0); signal clk, read, rst : STD_LOGIC; signal sensor : UNSIGNED(1 downto 0); signal D : UNSIGNED(7 downto 0); begin TT1 : T_Control port map (T_1, T_2, clk, sensor, read, rst, D); process begin rst <= '0'; clk <= '0'; wait for 5 ns; rst <= '1'; wait for 5 ns; rst <= '0'; T_in1 <= "000000000011"; T_in2 <= "000000000111"; read <= '0'; for i in 0 to 15 loop -- fill the FIFOs clk <= '0'; wait for 5ns; clk <= '1'; wait for 5 ns; end loop; assert (false) report "FIFOs full" severity NOTE; clk <= '0'; wait for 5ns; clk <= '1'; wait for 5 ns; read <= '1'; sensor <= "01"; for i in 0 to 15 loop -- empty the FIFOs clk <= '0'; wait for 5ns; clk <= '1'; wait for 5 ns; ASICs... THE COURSE 10.16 An Engine Controller 73 end loop; assert (false) report "FIFOs empty" severity NOTE; clk <= '0'; wait for 5ns; clk <= '1'; wait; end process; end; 74 SECTION 10 VHDL ASICS... THE COURSE 10.17 Summary Key terms and concepts: The use of an entity and an architecture The use of a configuration to bind entities and their architectures The compile, elaboration, initialization, and simulation steps Types, subtypes, and their use in expressions The logic systems based on BIT and Std_Logic_1164 types The use of the IEEE synthesis packages for BIT arithmetic Ports and port modes Initial values and the difference between simulation and hardware The difference between a signal and a variable The different assignment statements and the timing of updates The process and wait statements ASICs... THE COURSE 10.17 Summary 75 VHDL summary VHDL feature Example 93LRM Comments -- this is a comment 13.8 Literals (fixed-value items) 12 1.0E6 '1' "110" 'Z' 2#1111_1111# "Hello world" STRING'("110") 13.4 Identifiers (case-insensitive, start with letter) a_good_name Same same 2_Bad bad_ _bad very__bad 13.3 Several basic units of code entity architecture configuration 1.1–1.3 Connections made through ports port (signal in i : BIT; out o : BIT); 4.3 Default expression port (i : BIT := '1'); -- i='1' if left open 4.3 No built-in logic-value system. BIT and BIT_VECTOR (STD). type BIT is ('0', '1'); -- predefined signal myArray: BIT_VECTOR (7 downto 0); 14.2 Arrays myArray(1 downto 0) <= ('0', '1'); 3.2.1 Two basic types of logic signals a signal corresponds to a real wire a variable is a memory location in RAM 4.3.1.2 4.3.1.3 Types and explicit initial/default value signal ONE : BIT := '1' ; 4.3.2 Implicit initial/default value BIT'LEFT = '0' 4.3.2 Predefined attributes clk'EVENT, clk'STABLE 14.1 Sequential statements inside pro- cesses model things that happen one after another and repeat process begin wait until alarm = ring; eat; work; sleep; end process; 8 Timing with wait statement wait for 1 ns; -- not wait 1 ns wait on light until light = green; 8.1 Update to signals occurs at the end of a simulation cycle signal <= 1; -- delta time delay signal <= variable1 after 2 ns; 8.3 Update to variables is immediate variable := 1; -- immediate update 8.4 Processes and concurrent state- ments model things that happen at the same time process begin rain; end process; process begin sing; end process; process begin dance; end process; 9.2 IEEE Std_Logic_1164 (defines logic operators on 1164 types) STD_ULOGIC, STD_LOGIC, STD_ULOGIC_VECTOR, STD_LOGIC_VECTOR type STD_ULOGIC is ('U','X','0','1','Z','W','L','H','-'); — IEEE Numeric_Bit and Numeric_Std (defines arithmetic operators on BIT and 1164 types) UNSIGNED and SIGNED X <= "10" * "01" -- OK with numeric pkgs. — 76 SECTION 10 VHDL ASICS... THE COURSE