410 likes | 426 Views
Learn how to model, simulate, and design digital systems using VHDL with a focus on hierarchical models, different levels of abstraction, and automated synthesis. Understand the anatomy of a VHDL model and how to verify designs through simulation.
E N D
Modeling & SimulatingASIC Designs with VHDL Reference: Smith text: Chapters 10 & 12
HDLs in Digital System Design • Model and document digital systems • Hierarchical models • System, RTL (Register Transfer Level), Gates • Different levels of abstraction • Behavior, structure • Verify circuit/system design via simulation • Automated synthesis of circuits from HDL models • using a technology library • output is primitive cell-level netlist (gates, flip flops, etc.)
Anatomy of a VHDL model • “Entity” describes the external view of a component • “Architecture” describes the internal behavior and/or structure of the component • Example: 1-bit full adder A B Cin Full Adder Sum Cout
Example: 1-Bit Full Adder entity full_add1 is port ( -- I/O ports a: in bit; -- addend input b: in bit; -- augend input cin: in bit; -- carry input sum: out bit; -- sum output cout: out bit); -- carry output end full_add1 ; I/O Port Declarations Comments follow double-dash Type of signal Signal name Signal direction (mode)
Port: Identifier: Mode Data_type; • Identifier (naming) rules: • Can consist of alphabet characters (a-z), numbers (0-9), and underscore (_) • First character must be a letter (a-z) • Last character cannot be an underscore • Consecutive underscores are not allowed • Upper and lower case are equivalent (case insensitive) • VHDL keywords cannot be used as identifiers 1 of 3
Port: Identifier:Mode Data_type; • Mode • in - driven into the entity from an external source (can read, but not update within architecture) • out - driven from within the entity (can drive but not read within architecture) • inout – bidirectional; drivers both within the entity and external (can read or write within architecture) • buffer – like “out” but can read and write 2 of 3
Port: Identifier: Mode Data_type; • Data_type: = scalar or aggregate signal type • Scalar (single-value) signal types: • bit – values are ‘0’ or ‘1’ • std_logic – same as bit, but for standard simulation/synthesis (IEEE standard 1164) • integer- values [-231 … +(231-1)] on 32-bit host • Aggregate (multi-value) signal types: • bit_vector – array of bits • std_logic_vector – array of std_logic (IEEE 1164) • All vectors must have a range specified: Ex. bit_vector(3 downto 0) or std_logic_vector(0 to 3) 3 of 3
IEEE std_logic_1164 package -- For simulation and synthesis, std_logic preferred over bit. -- Provides additional logic states as data values type STD_LOGIC is ( 'U', -- Uninitialized 'X', -- Forcing Unknown '0', -- Forcing 0 '1', -- Forcing 1 'Z', -- High Impedance 'W', -- Weak Unknown 'L', -- Weak 0 'H', -- Weak 1 '-' -- Don't Care); You must include the library and package declarations in the VHDL model before the entity. (Example on next slide)
Example: 8-bit full adder -- Adder with 8-bit inputs/outputs library ieee; --supplied library use ieee.std_logic_1164.all; --package of definitions entity full_add8 is port ( a: in std_logic_vector(7 downto 0); b: in std_logic_vector(7 downto 0); cin: in std_logic; sum: out std_logic _vector(7 downto 0); cout: out std_logic); end full_add8 ;
Format for Architecture body architecture architecture_name of entity_name is -- data type definitions (ie, states, arrays, etc.) -- internal signal declarations signal signal_name: signal_type; : signal signal_name: signal_type; -- component declarations – see format below -- function and procedure declarations begin --behavior of the model is described here and consists of concurrent interconnecting: -- component instantiations -- processes -- concurrent statements including: Signal Assignment statements When-Else statements With-Select-When statements end architecture architecture_name; Note: entity and architecture in the end statement is optional.
Architecture defines function/structure -- behavioral model (no circuit structure implied) architecture dataflow of full_add1 is signal x1: std_logic; -- internal signal begin x1 <= a xor b after 1 ns; sum <= x1 xorcin after 1 ns; cout <= (a and b) or (a and cin) or (b and cin) after 1 ns; end;
Structural architecture example(no “behavior” specified) architecture structure of full_add1 is component xor-- declare component to be used port (x,y: in bit; z: out bit); end component; for all: xor use entity work.xor(eqns); -- if multiple arch’s signal x1: bit; -- signal internal to this component begin G1: xor port map (a, b, x1); -- instantiate 1stxor gate G2: xor port map (x1, cin, sum); -- instantiate 2ndxor gate …add circuit for carry output… end;
Associating signals with formal ports component AndGate port (Ain_1, Ain_2 : in BIT; -- formal parameters Aout : out BIT); end component; -- positional association: A1:AndGate port map (X, Y, Z1); -- named association: A2:AndGate port map (Ain_2=>Y, Aout=>Z2, Ain_1=>X); -- both (positional must begin from leftmost formal): A3:AndGate port map (X, Aout => Z3, Ain_2 => Y);
Example: D flip-flop entity DFF is port (Preset: in bit; Clear: in bit; Clock: in bit; Data: in bit; Q: out bit; Qbar: out bit); end DFF; Data Clock Preset Q Qbar Clear
7474 D flip-flop equations architecture eqns of DFF is signal A,B,C,D: bit; signal QInt, QBarInt: bit; begin A <= not (Preset and D and B) after 1 ns; B <= not (A and Clear and Clock) after 1 ns; C <= not (B and Clock and D) after 1 ns; D <= not (C and Clear and Data) after 1 ns; Qint <= not (Preset and B and QbarInt) after 1 ns; QBarInt <= not (QInt and Clear and C) after 1 ns; Q <= QInt; -- Can drive but not read “outs” QBar <= QBarInt; -- Can read & drive “internals” end;
D(3) D(2) D(1) D(0) 4-bit Register (Structural Model) entity Register4 is port ( D: in bit_vector(0 to 3); Q: out bit_vector(0 to 3); Clk: in bit; Clr: in bit; Pre: in bit); end Register4; CLK PRE CLR Q(0) Q(1) Q(2) Q(3)
Register Structure architecture structure of Register4 is component DFF -- declare library component to be used port (Preset: in bit; Clear: in bit; Clock: in bit; Data: in bit; Q: out bit; Qbar: out bit); end component; signal Qbar: bit_vector(0 to 3); -- dummy for unused FF outputs begin -- Signals connect to ports in order listed above F3: DFF port map (Pre, Clr, Clk, D(3), Q(3), Qbar(3)); F2: DFF port map (Pre, Clr, Clk, D(2), Q(2), Qbar(2)); F1: DFF port map (Pre, Clr, Clk, D(1), Q(1), Qbar(1)); F0: DFF port map (Pre, Clr, Clk, D(0), Q(0), Qbar(0)); end;
Conditional Signal Assignment signal a,b,c,d,y: std_logic; signal S: std_logic_vector(0 to 1); begin with S select y <= a after 1 ns when “00”, b after 1 ns when “01”, c after 1 ns when “10”, d after 1 ns when “11”; --Alternative “default”: d after 1 ns when others; 4-to-1 Mux 00 01 10 11 a b c d y S
32-bit-wide 4-to-1 multiplexer signal a,b,c,d,y: bit_vector(0 to 31); signal S: bit_vector(0 to 1); begin with S select y <= a after 1 ns when “00”, b after 1 ns when “01”, c after 1 ns when “10”, d after 1 ns when “11”; --a,b,c,d,y can be any type, as long as they are the same 4-to-1 Mux 00 01 10 11 a b c d y S
Conditional Signal Assignment – Alternate Format y <= a after 1 ns when (S=“00”) else b after 1 ns when (S=“01”) else c after 1 ns when (S=“10”) else d after 1 ns; Use any boolean expression for each condition: y <= a after 1 ns when (F=‘1’) and (G=‘0’) … 4-to-1 Mux 00 01 10 11 a b c d y S
VHDL “Process” Construct [label:] process (sensitivity list) declarations begin sequential statements end process; • Process statements executed once at start of simulation • Process halts at “end” until an event occurs on a signal in the “sensitivity list” • Allows conventional programming language methods to describe circuit behavior
D Q CLK Modeling sequential behavior -- Edge-triggered flip flop/register entity DFF is port (D,CLK: in bit; Q: out bit); end DFF; architecture behave of DFF is begin process(clk) -- “process sensitivity list” begin if (clk’event and clk=‘1’) then Q <= D after 1 ns; end if; end process; end; • Process statements executed sequentially (sequential statements) • clk’event is an attribute of signal clk which is TRUE if an event has occurred on clk at the current simulation time
Edge-triggered flip-flop Alternative methods for specifying clock process (clk) begin if rising_edge(clk) then -- std_logic_1164 function Q <= D ; end if; end process; Leonardo also recognizes not clk’stable as equivalent to clk’event
D Q CLK Alternative to sensitivity list process -- no “sensitivity list” begin wait on clk; -- suspend process until event on clk if (clk=‘1’) then Q <= D after 1 ns; end if; end process; • Other “wait” formats: wait until (clk’event and clk=‘1’) wait for 20 ns; • This format does not allow for asynchronous controls • Process executes endlessly if no sensitivity list or wait statement!
Level-Sensitive D latch vs. D flip-flop entity Dlatch is port (D,CLK: in bit; Q: out bit); end Dlatch; architecture behave of Dlatch is begin process(D, clk) begin if (clk=‘1’) then Q <= D after 1 ns; end if; end process; end; Latch, Q changes whenever the latch is enabled by CLK=‘1’ (rather than edge-triggered) D Q CLK
Defining a “register” for an RTL model (not gate-level) entity Reg8 is port (D: in bit_vector(0 to 7); Q: out bit_vector(0 to 7); LD: in bit); end Reg8; architecture behave of Reg8 is begin process(LD) begin if (LD’event and LD=‘1’) then Q <= D after 1 ns; end if; end process; end; D and Q could be any abstract data type D(0 to 7) Reg8 LD Q(0 to 7)
Basic format for synchronous and asynchronous inputs process (clock, asynchronously_used_signals ) begin if (boolean_expression) then asynchronous signal_assignments elsif (boolean_expression) then asynchronous signal assignments elsif (clock’event and clock = contstant) then synchronous signal_assignments end if ; end process;
CLR D Q CLK PRE Synchronous vs. Asynchronous Flip-Flop Inputs entity DFF is port (D,CLK: in bit; PRE,CLR: in bit; Q: out bit); end DFF; architecture behave of DFF is begin process(clk,PRE,CLR) begin if (CLR=‘0’) then -- async CLR has precedence Q <= ‘0’ after 1 ns; elsif (PRE=‘0’) then -- then async PRE has precedence Q <= ‘1’ after 1 ns; elsif (clk’event and clk=‘1’) then Q <= D after 1 ns; -- sync operation only if CLR=PRE=‘1’ end if; end process; end;
Modeling Finite State Machines (Synchronous Sequential Circuits) • FSM design & synthesis process: • Design state diagram (behavior) • Derive state table • Reduce state table • Choose a state assignment • Derive output equations • Derive flip-flop excitation equations • Synthesis steps 2-6 can be automated, given the state diagram
Synchronous Sequential Circuit Model Comb. Logic Inputs x Outputs z Present State y Next State Y FFs Clock Mealy Outputs z = f(x,y), Moore Outputs z = f(y) Next State Y = f(x,y)
FSM Example – entity definition entity seqckt is port ( x: in bit; -- FSM input z: out bit; -- FSM output clk: in bit ); -- clock end seqckt;
FSM Example - behavioral model architecture behave of seqckt is type states is (A,B,C); -- symbolic state names (enumerate) signal curr_state,next_state: states; begin -- Model the memory elements of the FSM process (clk) begin if (clk’event and clk=‘1’) then pres_state <= next_state; end if; end process; (continue on next slide)
FSM Example - continued -- Model next-state and output functions of the FSM process (x, pres_state) -- function inputs begin case pres_state is -- describe each state when A => if (x = ‘0’) then z <= ‘0’; next_state <= A; else -- if (x = ‘1’) z <= ‘0’; next_state <= B; end if; (continue next slide for pres_state = B and C)
FSM Example (continued) when B => if (x=‘0’) then z <= ‘0’; next_state <= A; else z <= ‘1’; next_state <= C; end if; when C => if (x=‘0’) then z <= ‘0’; next_state <= C; else z <= ‘1’; next_state <= A; end if; end case; end process;
Alternative Format for Output and Next State Functions -- Output function z <= ‘1’ when ((curr_state = B) and (x = ‘1’)) or ((curr_state = C) and (x = ‘1’)) else ‘0’; -- Next state function next_state <= A when ((curr_state = A) and (x = ‘0’)) or ((curr_state = B) and (x = ‘0’)) or ((curr_state = C) and (x = ‘1’)) else B when ((curr_state = 1) and (x = ‘1’)) else C;
library IEEE; use IEEE.STD_LOGIC_1164.all; entity SM1 is port (aIn, clk : in Std_logic; yOut: out Std_logic); end SM1; architecture Moore of SM1 is type state is (s1, s2, s3, s4); signal pS, nS : state; begin process (aIn, pS) begin – next state and output functions case pS is when s1 => yOut <= '0'; nS <= s4; --Moore: yOut = f(pS) when s2 => yOut <= '1'; nS <= s3; when s3 => yOut <= '1'; nS <= s1; when s4 => yOut <= '1'; nS <= s2; end case; end process; process begin wait until clk = '1'; pS <= nS; -- update state variable on next clock end process; end Moore;
library IEEE; use IEEE.STD_LOGIC_1164.all; entity SM2 is port (aIn, clk : in Std_logic; yOut: out Std_logic); end SM2; architecture Mealyof SM2 is type state is (s1, s2, s3, s4); signal pS, nS : state; begin process(aIn, pS) begin -- Mealy: yOut& nS are functions of aIn and pS case pS is when s1 => if (aIn = '1') then yOut <= '0'; nS <= s4; else yOut <= '1'; nS <= s3; end if; when s2 => yOut <= '1'; nS <= s3; when s3 => yOut <= '1'; nS <= s1; when s4 => if (aIn = '1') then yOut <= '1'; nS <= s2; else yOut <= '0'; nS <= s1; end if; end case; end process; process begin wait until clk = '1' ; pS <= nS; end process; end Mealy;
when s1 => -- initiate row access ras <= ’0’ ; cas <= ’1’ ; ready <= ’0’ ; next_state <= s2 ; when s2 => -- initiate column access ras <= ’0’ ; cas <= ’0’ ; ready <= ’0’ ; if (cs = ’0’) then next_state <= s0 ; -- end of operation if cs = 0 else next_state <= s2 ; -- wait in s2 for cs = 0 end if ; when s3 => -- start cas-before-ras refresh ras <= ’1’ ; cas <= ’0’ ; ready <= ’0’ ; next_state <= s4 ; when s4 => -- complete cas-before-ras refresh ras <= ’0’ ; cas <= ’0’ ; ready <= ’0’ ; next_state <= s0 ; end case ; end process ; end rtl ;
Synthesizing arithmetic circuits(12.6.5, 12.6.9, 12.6.10) • Leonardo recognizes overloaded operators and generated corresponding circuits: “+”, “-”, “*”, and “abs” • Special operations: “+1”, “-1”, unary “-” • Relational Operators: “=“, “/=“, “<“, “>“, “<=“, “>=“ • Use “ranged integers” instead of unbound to minimize generated logic. signal i : integer range 0 to 15;