Professional Documents
Culture Documents
Operators and Precendence Logical operators: Used in conditional statements and in logic equations NOT AND OR NAND NOR XOR XNOR (XNOR not in original VHDL, added in 1993) Relational Operators: Used in conditional statements = equal to /= not equal to < less than <= less then or equal to > greater than >= greater than or equal to Precedence: Highest Lowest
Evaluation Rules: 1. Operators evaluated in order of precedence (highest evaluated 1st) 2. Operators of equal precedence evaluated from left to right 3. Deepest nested parentheses evaluated 1st Because of #2 you should use lots of parentheses Addition Operators: Used for adders, subtractors, counters, etc. with bit_vector and std_logic_vector + addition subtraction Note: you should use std_logic_vector and the std_arith package as follows: library IEEE; use IEEE.std_logic_1164.all; use work.std_arith.all;
VHDL Modeling
M PUSH POP FIFO Control Logic ADD WE INIT FULL EMPTY NOPOP NOPUSH CLK Din ADD RAM 2N words M bits/word WE Dout M
VHDL Modeling
library ieee; use ieee.std_logic_1164.all; use work.std_arith.all; entity FIFO_LOGIC is generic (N: integer := 3); port (clk,push,pop,init: in std_logic; add: out std_logic_vector(N-1 downto 0); full,empty,we,nopush,nopop: buffer std_logic); end FIFO_LOGIC; architecture RTL of FIFO_LOGIC is signal wptr, rptr: std_logic_vector(N-1 downto 0); signal lastop: std_logic; begin sync: process (clk) begin if (clk'event and clk = '1') then if (init = '1') then -- initialization -wptr <= (others => '0'); rptr <= (others => '0'); lastop <= '0'; elsif (pop = '1' and empty = '0') then -- pop -rptr <= rptr + 1; lastop <= '0'; elsif (push = '1' and full = '0') then -- push -wptr <= wptr + 1; lastop <= '1'; end if; -- otherwise all Fs hold their value -end if; end process sync; comb: process (push,pop,wptr,rptr,lastop,full,empty) begin -- full and empty flags -if (rptr = wptr) then if (lastop = '1') then full <= '1'; empty <= '0'; else full <= '0';
VHDL Modeling
empty <= '1'; end if; else full <= '0'; empty <= '0'; end if; -- address, write enable and nopush/nopop logic -if (pop = '0' and push = '0') then -- no operation -add <= rptr; we <= '0'; nopush <= '0'; nopop <= '0'; elsif (pop = '0' and push = '1') then -- push only -add <= wptr; nopop <= '0'; if (full = '0') then -- valid write condition -we <= '1'; nopush <= '0'; else -- no write condition -we <= '0'; nopush <= '1'; end if; elsif (pop = '1' and push = '0') then -- pop only -add <= rptr; nopush <= '0'; we <= '0'; if (empty = '0') then -- valid read condition -nopop <= '0'; else nopop <= '1'; -- no red condition -end if; else -- push and pop at same time if (empty = 0) then -- valid pop -add <= rptr; we <= '0'; nopush <= '1'; nopop <= '0'; else add <= wptr; we <= 1;
VHDL Modeling
nopush <= 0; nopop <= 1; end if; end if; end process comb; end architecture RTL;
Note: If you synthesize this model in the Cypress 374 CPLD and simulate the synthesized circuit, you will notice that lastop is inverted compared to the values indicated in the VHDL model. However, since this is an internal node and not a primary output of the CPLD, then the synthesis tool takes to liberty of inverting the node values to help minimize the resultant CPLD logic utilization. But the important thing is that the circuit works properly from the standpoint of the I/O behavior (so you wouldnt know that lastop was inverted if you didnt monitor that node during simulation). Synthesis tools may also eliminate internal nodes of the VHDL model as well as introduce new internal nodes all in the name of design optimization.
VHDL Modeling
Signal assignments in a process: All expressions based on current value of signals (right-hand side of <=, values at start of process execution) Assigned signals updated at end of process execution Example: process (CK) begin D <= Q xor CIN; if (CKevent and CK = 1) then Q <= D; end if; COUT <= Q xor CIN; end process; Case 1: sensitivity list consists only of CK (no other implied signals) on rising clock edge, Q gets value of D based on Q and CIN from previous execution of process if CIN is available prior to falling edge of CK then count works as expected otherwise, it does not also COUT is updated on falling edge of CK and not when Q changes Case 2: sensitivity list consists of CK, CIN and Q (or CIN and Q implied) D and COUT updated anytime Q or CIN changes on rising clock edge, Q gets updated value of D & count works as expected Signal assignments in a concurrent statement: Like a process with implied sensitivity list (right-hand side of <=) multiple concurrent statements work like multiple 1-line processes updates assigned signal whenever right-hand has event Example: D <= Q xor CIN; COUT <= Q xor CIN; process (CK) begin if (CKevent and CK = 1) then Q <= D; end if; end process; D and COUT updated anytime Q or CIN changes on rising clock edge, Q gets updated value of D & count works as expected same as if we put the 2 concurrent statements in process with Q & CIN in sensitivity list
VHDL Modeling
Sequential Statements: if-then-else example: general format: if (condition) then if (count = 00) then do some stuff a <= b; elsif (condition) then elsif (count = 11) then do some other stuff a <= c; else else do some junk a <= d; end if; end if; elsif and else clauses are optional BUT incompletely specified if-then-else (no else) implies memory element case-when general format: case expression is when value => do stuff when value => do more stuff others => do junk end case;
example: case count is when 00 => a <= b; when 11 => a <= c; others => a <= d; end case;
for-loop general format: example: [label:] for identifier in range loop init: for k in N-1 downto 0 loop do a bunch of junk Q(k) <= 0; end loop [label]; end loop init; note: variable k implied in for-loop and does not need to be declared while-loop general format: [label:] while condition loop do silly stuff end loop [label];
example: init: while (k > 0) loop Q(k) <= 0 k := k 1; end loop init; note: variable k must be declared as variable in process (between sensitivity list and begin with format: variable k: integer := N-1;
VHDL Modeling
Concurrent Statements: logical operators with signal assignement <= example: Z <= A and B; when-else general format: expression when condition else expression when condition else expression when others;
with-select-when we will discuss this one later, after we talk about defining types
VHDL Modeling
Initialization: All processes (and concurrent statements) evaluated once then again and again until there are no events in sensitivity list If explicit initialization is not defined (using := assignment operator) then a bit is assigned 0 and a std_logic is assigned U When no events happen for a given process sensitivity list then that process is suspended Simulation cycle: 1. Time is advanced until next entry in time queue where signals are to be updated (for example, PIs) which cause events on these signals 2. A simulation cycle starts at that point in time and processes & concurrent statements sensitive to events (during the current simulation time) on those signals will be executed 3. Simulation times for subsequent simulation cycles are determined and scheduled based on internal signals being updated from processes or concurrent statements Note: we will talk about specifying delays later, right now we consider only delta () delays = infinitesimal delays 4. If there are any delay time queues go to Step 2, else go to Step 1 Examples: Z <= X after 5ns; -- specified delay scheduled as entry in time queue Z <= X; -- delay scheduled as entry in delay time queue
VHDL Modeling