29-08-2014, 02:54 PM
First-In First-Out (FIFO) Control Logic
First-In First-Ou.pdf (Size: 26.16 KB / Downloads: 12)
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 NOT
Relational operators
Lowest Rest of logical operators
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;
First-In First-Out (FIFO) Control Logic VHDL Modeling Example
A common problem in ASIC design is constructing a FIFO from a RAM by designing the
control logic to generate the address (ADD) and write enable (WE) to the RAM so that
the first data word written into the RAM is also the first data word retrieved from the
RAM. Therefore, we want to write a parameterized VHDL model for an N-bit FIFO.
The VHDL model will implement the logic required to make a pipelined RAM operate as
the FIFO. As discussed in class, the RAM is assumed to have separate data inputs and
outputs, an N-bit address bus (ADD) and an active high write enable (WE). The inputs to
the FIFO/Stack logic include PUSH, POP, INIT (all active high) in addition to the rising
edge triggered CLK input. The FIFO logic will not only supply the address and write
enable to the RAM, but will also supply active high flags for FULL, EMPTY, NOPOP
and NOPUSH conditions. The NOPOP and NOPUSH flags indicate that no FIFO read or
write operation was executed due to one of the following conditions:
1. simultaneous assertion of both PUSH and POP - the POP takes priority => NOPUSH
2. assertion of PUSH when the FIFO is full => NOPUSH
3. assertion of POP when the FIFO is empty => NOPOP
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 (CK’event 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 (CK’event 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
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