big

big
Internet Engineering
Dr. Jarosław Sugier
Digital Circuits Design
Part 3: The VHDL language
3-1
1) ENTITIES AND ARCHITECTURES
library UNISIM;
use UNISIM.VComponents.all;
entity HalfAdder is
port ( A : in STD_LOGIC;
B : in STD_LOGIC;
S : out STD_LOGIC;
C : out STD_LOGIC);
end entity HalfAdder;
architecture Structural of HalfAdder is
begin
XOR_gate : XOR2 port map ( A, B, S );
AND_gate : AND2 port map ( A, B, C );
end architecture Structural;
architecture Dataflow of HalfAdder is
begin
S <= A xor B;
C <= A and B;
end architecture Dataflow;
3-2
1
architecture Behavioral of HalfAdder is
begin
process( A, B )
begin
-- Sum
if A /= B then
S <= '1';
else
S <= '0';
end if;
-- Carry
if A = '1' and B = '1' then
C <= '1';
else
C <= '0';
end if;
end process;
end architecture Behavioral;
3-3
Another example: ISE test bench code
entity tbw_HalfAdder is
end tbw_HalfAdder;
architecture behavior of tbw_HalfAdder is
(...)
begin
-- Instantiate the Unit Under Test (UUT)
uut: HalfAdder port map (
A => A,
B => B,
S => S,
C => C
);
A <= '0', '1' after 100 ns, '0' after 300 ns;
B <= '0', '1' after 200 ns, '0' after 400 ns;
end;
3-4
2
Port modes
Synthesis:
1) in – READ ONLY
2) out – WRITE ONLY
3)
inout – bidirectional (3-state buffers, etc.)
4)
buffer – „out with read capability”
!!
3-5
Internal signals
entity AndNand is
port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
OUT_And : out STD_LOGIC;
OUT_Nand : out STD_LOGIC);
end AndNand;
architecture DataflowBad of AndNand is
begin
OUT_And <= A and B and C;
OUT_Nand <= not OUT_And;
end DataflowBad;
HDLParsers:1401 - Object OUT_And of mode OUT can not be read.
architecture DataflowOK of AndNand is
signal Int_And : STD_LOGIC;
begin
Int_And <= A and B and C;
OUT_And <= Int_And;
OUT_Nand <= not Int_And;
end DataflowOK;
3-6
3
Vectors and Bit-string Literals
type STD_LOGIC_VECTOR is array (NATURAL range <>) of STD_LOGIC;
signal DataBus
(...)
DataBus
DataBus
DataBus
DataBus
DataBus
DataBus
<=
<=
<=
<=
<=
<=
: STD_LOGIC_VECTOR( 7 downto 0);
"10000000";
B"1000_0000";
X"80";
( '1', '0', '0', '0', '0', '0', '0', '0' );
( '1', others => '0' );
( 7 => '1', others => '0' );
DataBus <= ( others => '0' );
HalfByte <= DataBus( 7 downto 4 );
MSB <= DataBus( 7 );
3-7
Concatenation operator ‘&’
signal ASCII : STD_LOGIC_VECTOR( 7 downto 0 );
signal Digit : STD_LOGIC_VECTOR( 3 downto 0 );
(...)
ASCII <= "0011" & Digit;
-- X"3" & Digit;
ASCII <= X"3" & Digit ( 3 ) & Digit ( 2 ) &
Digit ( 1 ) & Digit ( 0 );
(...)
-- Shift right (this must be synchronous!):
ASCII <= '0' & ASCII( 7 downto 1 );
-- Arithmetic shift right:
ASCII <= ASCII( 7 ) & ASCII( 7 downto 1 );
-- Rotate left:
ASCII <= ASCII( 6 downto 0 ) & ASCII( 7 );
3-8
4
generic Clause
entity identifier is
generic ( parameter_declarations ); -- optional
port ( port_declarations );
-- optional
[ declarations ]
-- optional
begin
\__ optional
[ statements ]
/
end entity identifier ;
entity Buf is
generic ( N : POSITIVE := 8;
-- data width
Delay : DELAY_LENGTH := 2.5 ns );
port ( Input : in STD_LOGIC_VECTOR( N-1 downto 0 );
OE
: in STD_LOGIC;
Output : out STD_LOGIC_VECTOR( N-1 downto 0 ) );
end entity Buf;
3-9
2) CONCURRENT INSTRUCTIONS
Signal assignment
z <= x;
z <= ( x1 and x2 ) or ( ( x3 nand x4 ) xor x5 );
-- By default:
z <= x after 4 ns;
z <= x;
<=>
<=>
z <= inertial x after 4 ns;
z <= inertial x after 0 ns;
-- Multiple delayed assignments
A <= '0', '1' after 100 ns, '0' after 300 ns;
-- E.g. in loops:
Clk <= '1', '0' after ClkPeriod / 2;
3-10
5
Conditional assignment
when...else
entity MUX_4 is
port( A, B, C, D : in STD_LOGIC;
Sel : in STD_LOGIC_VECTOR( 1 downto 0 );
Z : out STD_LOGIC );
end MUX_4;
architecture Dataflow of MUX_4 is
begin
Z <= A when Sel = "00" else
B when Sel = "01" else
... or better ...
C when Sel = "10" else
D when Sel = "11" else
D;
'X';
end Dataflow;
3-11
•
ATTENTION
Z <= ‘1’ when A = ‘1’ and B = ‘1’ else
‘0’ when A = ‘0’ and B = ‘0’;
???
WARNING:Xst:737 - Found 1-bit latch for signal <Y>. Latches may be generated
from incomplete case or if statements. We do not recommend the use of
latches in FPGA/CPLD designs, as they may lead to timing problems.
3-12
6
Selective assignment
with ... select
entity MUX_4 is
port( A, B, C, D : in STD_LOGIC;
Sel : in STD_LOGIC_VECTOR( 1 downto 0 );
Y : out STD_LOGIC );
end MUX_4;
architecture Dataflow2 of MUX_4 is
begin
with Sel select
Y <= A when "00",
B when "01",
C when "10",
D when others;
end Dataflow2;
3-13
Components and Instances
entity XOR_2IN is
generic( Tp : DELAY_LENGTH );
port ( I1, I2 : in STD_LOGIC;
O : out STD_LOGIC);
end XOR_2IN;
architecture A of XOR_2IN is
begin
O <= I1 xor I2 after Tp;
end A;
entity AND_2IN is
generic( Tp : DELAY_LENGTH );
port (I1, I2 : in STD_LOGIC;
O : out STD_LOGIC);
end AND_2IN;
architecture A of AND_2IN is
begin
O <= I1 and I2 after Tp;
end A;
entity HalfAdder is
(...)
architecture Structural of HalfAdder is
component XOR_2IN is
generic( Tp : DELAY_LENGTH );
port ( I1, I2 : in STD_LOGIC; O : out STD_LOGIC);
end component;
component AND_2IN is
generic( Tp : DELAY_LENGTH );
port ( I1, I2 : in STD_LOGIC; O : out STD_LOGIC);
end component;
begin
XOR_gate : XOR_2IN generic map( 5 ns ) port map( A, B, S );
AND_gate : AND_2IN generic map( Tp => 3 ns )
port map( O=>C, I1=>A, I2=>B );
end architecture Structural;
3-14
7
VHDL code from ISE schematic
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library UNISIM;
use UNISIM.Vcomponents.all;
entity CntAsync
port ( CE :
Clk :
Q0 :
Q1 :
Q2 :
end CntAsync;
is
in
in
out
out
out
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC);
architecture BEHAVIORAL of CntAsync is
signal
signal
signal
signal
signal
signal
XLXN_1
XLXN_2
XLXN_3
Q0_DUMMY
Q1_DUMMY
Q2_DUMMY
:
:
:
:
:
:
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
component INV
port ( I : in
O : out
end component;
component FDE
port ( C :
CE :
D :
Q :
end component;
in
in
in
out
STD_LOGIC;
STD_LOGIC);
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC);
Generations: a)
component FD_1
port ( C : in
D : in
Q : out
end component;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC);
begin
Q0 <= Q0_DUMMY;
Q1 <= Q1_DUMMY;
Q2 <= Q2_DUMMY;
XLXI_1 : FDE
port map (C=>Clk,
CE=>CE,
D=>XLXN_1,
Q=>Q0_DUMMY);
XLXI_2 : INV
port map (I=>Q0_DUMMY,
O=>XLXN_1);
XLXI_3 : FD_1
port map (C=>Q0_DUMMY,
D=>XLXN_2,
Q=>Q1_DUMMY);
XLXI_4 : INV
port map (I=>Q1_DUMMY,
O=>XLXN_2);
XLXI_5 : FD_1
port map (C=>Q1_DUMMY,
D=>XLXN_3,
Q=>Q2_DUMMY);
XLXI_6 : INV
port map (I=>Q2_DUMMY,
O=>XLXN_3);
end BEHAVIORAL;
3-15
for ... generate
entity FullAdder is
port ( A, B : in STD_LOGIC_VECTOR( 7 downto 0 );
CI
: in STD_LOGIC;
S
: out STD_LOGIC_VECTOR( 7 downto 0 );
CO
: out STD_LOGIC);
end FullAdder;
architecture Dataflow of FullAdder is
signal Cint : STD_LOGIC_VECTOR( 8 downto 0 );
begin
lb: for i in 0 to 7 generate
S(i) <= A(i) xor B(i) xor Cint(i);
Cint(i + 1) <= ( A(i) and B(i) ) or
( A(i) and Cint(i) ) or ( B(i) and Cint(i) );
end generate;
Cint( 0 ) <= CI;
CO <= Cint( 8 );
end Dataflow;
3-16
8
b)
if ... generate
label: if condition generate
-- label required
block_declarative_items \__ optional
begin
/
concurrent_statements
end generate label;
3-17
process instruction
[label:] process [ ( sensitivity_list ) ] [ is ]
[ declarative_items ]
begin
sequential_statements
end process [ label ];
process( A, B ) is
begin
if A /= B then
S <= '1';
else
S <= '0';
end if;
if A = '1' and B = '1' then
C <= '1';
else
C <= '0';
end if;
end process;
3-18
9
3) SEQUENTIAL INSTRUCTIONS
[label:] process [ ( sensitivity_list ) ] [ is ]
[ declarative_items ]
begin
sequential_statements
end process [ label ];
Instruction wait:
wait
wait
wait
wait
for 10 ns;
-- timeout
until clk = '1';
-- Boolean condition
until A > B and ( S1 or S2 );
on sig1, sig2;
-- sensitivity list
⇒ wait until ... – wait for event, i.e. signal change; alternative:
if Busy /= ’0’ then
wait until Busy = ’0’;
end if;
3-19
[ label: ] if
condition1 then
statements
elsif condition2 then
statements
...
else
statements
end if [ label ] ;
architecture DF of MUX_4
begin
Y <= A when Sel = "00"
B when Sel = "01"
C when Sel = "10"
D when Sel = "11"
'X';
end DF;
is
else
else
else
else
\_ optional
/
\_ optional
/
architecture DF_Eq of MUX_4 is
begin
process ( Sel, A, B, C, D )
begin
if Sel = "00" then
Y <= A;
elsif Sel = "01" then
Y <= B;
elsif Sel = "10" then
Y <= C;
elsif Sel = "11" then
Y <= D;
else
Y <= 'X';
end if;
end process;
end DF_Eq;
3-20
10
[ label: ] case expression is
when choice1 =>
statements
when choice2 => \_ opt.
statements
/
...
when others =>
\_ opt. if all choices
statements
/ covered
end case [ label ] ;
architecture DF2 of MUX is
begin
with Sel select
Y <= A when "00",
B when "01",
C when "10",
D when "11",
'X'when others;
end DF2;
architecture DF2_Eq of
begin
process ( Sel, A, B,
begin
case Sel is
when "00" =>
Y
when "01" =>
Y
when "10" =>
Y
when "11" =>
Y
when others => Y
end case;
end process;
end DF2_Eq;
MUX_4 is
C, D )
<=
<=
<=
<=
<=
A;
B;
C;
D;
'X';
3-21
[ label: ] loop
statements
-- use exit to abort
end loop [ label ] ;
[ label: ] for variable in range loop
statements
end loop [ label ] ;
[ label: ] while condition loop
statements
end loop [ label ] ;
next;
next outer_loop; -- label of loop instr.
next when A > B;
next this_loop when C = D or A > B;
exit;
exit outer_loop;
exit when A > B;
exit this_loop when C = D or A > B;
3-22
11
4) VHDL coding Techniques
Synchronous signals
entity DFF is
port ( D
: in STD_LOGIC;
Clk : in STD_LOGIC;
Q
: out STD_LOGIC );
end DFF;
entity TFF is
port ( T
: in STD_LOGIC;
Clk : in STD_LOGIC;
Q
: out STD_LOGIC );
end TFF;
architecture RTL of DFF is
begin
process ( Clk )
begin
if Clk'Event and Clk = '1' then
Q <= D;
end if;
end process;
end architecture;
architecture RTL of TFF is
signal Q_int : STD_LOGIC := '0';
begin
Q <= Q_int;
process ( Clk )
begin
if Clk'Event and Clk = '1' then
if T = '1' then
Q_int <= not Q_int;
end if;
end if;
end process;
end architecture;
• Package STD_LOGIC_1164:
function rising_edge (signal s : STD_ULOGIC) return BOOLEAN;
function falling_edge (signal s : STD_ULOGIC) return BOOLEAN;
if Clk'Event and Clk = '1' then...
Clock Enable:
entity DFF_E is
port( D
: in
CE : in
Clk : in
Q
: out
end DFF_E;
=>
if rising_edge(Clk) then...
3-23
Asynchronous Clear + Enable:
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC );
architecture RTL of DFF_E is
begin
process ( Clk )
begin
if rising_edge( Clk ) then
if CE = '1' then
Q <= D;
end if;
end if;
end process;
end architecture;
entity DFF_CE
port( D
:
Clr :
CE :
Clk :
Q
:
end DFF_CE;
is
in
in
in
in
out
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC );
architecture RTL of DFF_CE is
begin
process ( Clk, Clr )
begin
if Clr = '1' then
Q <= '0';
elsif rising_edge(Clk) then
if CE = '1' then
Q <= D;
end if;
end if;
end process;
end architecture;
3-24
12
Synchronous Reset + Enable:
entity DFF_RE
port( D
:
Rst :
CE :
Clk :
Q
:
end DFF_RE;
is
in
in
in
in
out
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
STD_LOGIC );
architecture RTL of DFF_RE is
begin
process ( Clk )
begin
if rising_edge( Clk ) then
if Rst = '1' then
Q <= '0';
elsif CE = '1' then
Q <= D;
end if;
end if;
end process;
end architecture;
3-25
Shift register
entity SReg8b is
port ( Din : in STD_LOGIC;
Clk : in STD_LOGIC;
Q
: out STD_LOGIC_VECTOR( 7 downto 0 ) );
end SReg2b;
architecture RTL of SReg8b is
signal iQ : STD_LOGIC_VECTOR( 7 downto 0 );
begin
Q <= iQ;
process ( Clk )
begin
if rising_edge( Clk ) then
iQ( 7 downto 0 ) <= iQ( 6 downto 0 ) & Din;
end if;
end process;
end architecture;
3-26
13
architecture RTL of SimpleSch is
For example:
signal D, Q : STD_LOGIC;
begin
D <= ( E1 and E2 ) xor Q;
process( Clk )
begin
if rising_edge( Clk ) then
if Reset = '1' then
Q <= '0';
else
Q <= D;
end if;
end if;
end process;
Y <= Q;
end RTL;
3-27
Counter with asynchronous clear
!
3-28
14
Modulo counter (with clock enable and asynchronous clear):
process ( Clk, Clr )
begin
if Clr = '1 then
Cnt4b <= "0000";
elsif rising_edge( Clk ) and CE = '1' then
if Cnt4b = "1011" then
Cnt4b <= "0000";
else
Cnt4b <= Cnt4b + 1;
end if;
end if;
end process;
3-29
Loadable counter
3-30
15
Reversible (bi-directional) counter
3-31
Transparent latch
3-32
16
Transparent latch with asynchronous clear
3-33
Tri-state buffer
3-34
17
Sequential automata (Finite State Machines, FSM)
3-35
entity SequenceDet is
port ( Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
x : in STD_LOGIC;
z : out STD_LOGIC);
end SequenceDet;
architecture Behavioral of SequenceDet is
type state_type is ( A, B, C, D );
signal state, next_state : state_type;
begin
process1 : process( Clk )
begin
if rising_edge( Clk ) then
if Reset = '1' then
state <= A;
else
state <= next_state;
end if;
end if;
end process process1;
process2 : process( state, x )
begin
next_state <= state;
-- by default
case state is
when A =>
if x = '1' then
next_state <= B;
end if;
when B =>
if x = '1' then
next_state <= C;
else
next_state <= A;
end if;
when C =>
if x = '0' then
next_state <= D;
end if;
when D =>
if x = '0' then
next_state <= A;
else
next_state <= B;
end if;
end case;
end process process2;
-- In place of process3:
z <= '1' when state = D and x = '0'
else '0';
end Behavioral;
3-36
18
5) TYPES AND OPERATORS
Package STANDARD
type INTEGER is range --usually typical INTEGER-- ;
subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
subtype POSITIVE is INTEGER range 1 to INTEGER'HIGH;
type REAL is range --usually double precision f.p.-- ;
type BOOLEAN is (FALSE, TRUE);
type CHARACTER is ( --256 characters-- );
type STRING is array (POSITIVE range <>) of CHARACTER;
type BIT is ('0', '1');
type TIME is range --implementation defined-- ;
units
fs;
-- femtosecond
ps = 1000 fs; -- picosecond
ns = 1000 ps; -- nanosecond
us = 1000 ns; -- microsecond
ms = 1000 us; -- millisecond
sec = 1000 ms; -- second
min = 60 sec; -- minute
hr = 60 min; -- hour
end units;
subtype DELAY_LENGTH is TIME range 0 fs to TIME'HIGH;
3-37
Operators
**
abs
not
exponentiation,
absolute value,
complement,
numeric ** integer,
result numeric
abs numeric,
result numeric
not logic or boolean, result same
*
/
mod
rem
multiplication,
division,
modulo,
remainder,
numeric
numeric
integer
integer
+
-
unary plus,
unary minus,
+ numeric,
- numeric,
result numeric
result numeric
+
&
addition,
subtraction,
concatenation,
numeric + numeric,
numeric - numeric,
array or element,
result numeric
result numeric
result array
* numeric,
/ numeric,
mod integer,
rem integer,
result
result
result
result
numeric
numeric
integer
integer
3-38
19
sll
srl
sla
sra
rol
ror
shift left logical,
shift right log.,
shift left arith.,
shift right arith.,
rotate left,
rotate right,
=
/=
<
<=
>
>=
equality,
inequality,
less than,
less than or equal,
greater than,
greater than or equal,
and
or
nand
nor
xor
xnor
logical
logical
logical
logical
logical
logical
log.
log.
log.
log.
log.
log.
and,
or,
nand,
nor,
xor,
xnor,
array
array
array
array
array
array
sll
srl
sla
sra
rol
ror
integer,
integer,
integer,
integer,
integer,
integer,
result
result
result
result
result
result
log.
log.
log.
log.
log.
log.
array
array
array
array
array
array
or
or
or
or
or
or
boolean,
boolean,
boolean,
boolean,
boolean,
boolean,
result
result
result
result
result
result
same
same
same
same
same
same
boolean
boolean
boolean
boolean
boolean
boolean
result
result
result
result
result
result
same
same
same
same
same
same
3-39
STD_LOGIC_1164 Package
library IEEE;
use IEEE.STD_LOGIC_1164.all;
type STD_ULOGIC is ( 'U',
'X',
'0',
'1',
'Z',
'W',
'L',
'H',
'-'
);
U!
type STD_ULOGIC_VECTOR
STD_ULOGIC;
is
----------
Uninitialized
Forcing Unknown
Forcing 0
Forcing 1
High Impedance
Weak
Unknown
Weak
0
Weak
1
Don't care
array
(
NATURAL
range
<>
)
of
3-40
20
function resolved ( s : STD_ULOGIC_VECTOR ) return STD_ULOGIC;
constant resolution_table : stdlogic_table := (
----------------------------------------------------------| U
X
0
1
Z
W
L
H
|
|
---------------------------------------------------------( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
);
(...)
-------------------------------------------------------------------- *** industry standard logic type ***
------------------------------------------------------------------subtype STD_LOGIC is resolved STD_ULOGIC;
type STD_LOGIC_VECTOR is array ( NATURAL range <>) of STD_LOGIC;
3-41
constant and_table : stdlogic_table := (
-----------------------------------------------------| U
X
0
1
Z
W
L
H
( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), -( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' )
-);
constant or_table : stdlogic_table := (
-----------------------------------------------------| U
X
0
1
Z
W
L
H
( 'U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U' ), -( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' )
-);
|
|
|
|
|
|
|
|
|
|
U
X
0
1
Z
W
L
H
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
U
X
0
1
Z
W
L
H
-
|
|
|
|
|
|
|
|
|
|
3-42
21
6) Implementing algorithms in hardware
Transcoding a byte into two hexadecimal ASCII
digits
entity FSM_ByteToASCII is
port ( Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
DI : in STD_LOGIC_VECTOR (7 downto 0);
DIRdy : in STD_LOGIC;
TxBusy : in STD_LOGIC;
DO : out STD_LOGIC_VECTOR (7 downto 0);
DORdy : out STD_LOGIC;
Busy : out STD_LOGIC );
end FSM_SendByte;
architecture RTL of ByteToASCII is
type state_type is ( sReset, sReady, sWaitH, sSendH,
sWaitL, sSendL );
signal State, NextState : state_type;
signal regDI : STD_LOGIC_VECTOR (7 downto 0);
signal HalfByte : STD_LOGIC_VECTOR (3 downto 0);
3-43
(...)
begin
-- Input register (with CE)
regDI <= DI when rising_edge( Clk ) and State = sReady;
-- equivalent to the process seen in the template!
-- HalfByte selection
HalfByte <= regDI( 7 downto 4 ) when State = sSendH or
State = sWaitL
else regDI( 3 downto 0 );
-- State register (with asynchronous reset) = process1
process ( Clk, Reset )
begin
if Reset = '1' then
State <= sReset;
elsif rising_edge( Clk ) then
State <= NextState;
end if;
end process;
(...)
3-44
22
(...)
-- Next state decoding = process1
process ( State, DIRdy, TxBusy )
begin
NextState <= State; -- default
case State is
when sReset =>
NextState <= sReady;
when sReady =>
if DIRdy = '1' then
NextState <= sWaitH;
end if;
when sWaitL =>
if TxBusy = '0' then
NextState <= sSendL;
end if;
when sWaitH =>
if TxBusy = '0' then
NextState <= sSendH;
end if;
when sSendL =>
NextState <= sReady;
end case;
end process;
when sSendH =>
NextState <= sWaitL;
(...)
(...)
-- Outputs = process3
with HalfByte select
DO <= X"30" when "0000",
X"31" when "0001",
X"32" when "0010",
X"33" when "0011",
X"34" when "0100",
X"35" when "0101",
X"36" when "0110",
X"37" when "0111",
X"38" when "1000",
X"39" when "1001",
X"41" when "1010",
X"42" when "1011",
X"43" when "1100",
X"44" when "1101",
X"45" when "1110",
X"46" when others;
3-45
-- 0-15 => ASCII '0'-'F'
DORdy <= '1' when State = sSendH or State = sSendL
else '0';
Busy
<= '1' when State /= sReady
else '0';
end RTL;
3-46
23
Test Bench
entity Test_vhd is
end Test_vhd;
architecture behavior of Test_vhd is
-- component Declaration for the Unit Under Test (UUT)
component FSM_ByteToASCII
port(
Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
DI : in STD_LOGIC_VECTOR(7 downto 0);
DIRdy : in STD_LOGIC;
TxBusy : in STD_LOGIC;
DO : out STD_LOGIC_VECTOR(7 downto 0);
DORdy : out STD_LOGIC;
Busy : out STD_LOGIC
);
end component;
--Inputs
signal Clk : STD_LOGIC := '0';
signal Reset : STD_LOGIC := '0';
signal DIRdy : STD_LOGIC := '0';
signal TxBusy : STD_LOGIC := '0';
signal DI : STD_LOGIC_VECTOR(7 downto 0) := (others=>'0');
3-47
--Outputs
signal DO : STD_LOGIC_VECTOR(7 downto 0);
signal DORdy : STD_LOGIC;
signal Busy : STD_LOGIC;
-- AUX
constant Tclk : TIME := 1 us / 50;
-- MHz
begin
-- Instantiate the Unit Under Test (UUT)
uut: FSM_ByteToASCII port map(
Clk => Clk,
Reset => Reset,
DI => DI,
DIRdy => DIRdy,
TxBusy => TxBusy,
DO => DO,
DORdy => DORdy,
Busy => Busy
);
-- Global clock 50MHz
Clk <= not Clk after Tclk / 2;
-- Reset
Reset <= '1' after 300 ns, '0' after 300 ns + Tclk;
3-48
24
-- Byte source
process
type typeArray is array ( 0 to 3 )
of STD_LOGIC_VECTOR( 7 downto 0 );
variable arrBytes : typeArray := ( X"10", X"20", X"3A", X"4F" );
begin
wait for 500 ns;
for i in arrBytes'RANGE loop
if Busy = '1' then
wait until Busy = '0';
end if;
wait for 7.1 * Tclk;
DI <= arrBytes( i );
DIRdy <= '1';
wait for Tclk;
DIRdy <= '0';
end loop;
wait; -- will wait forever
end process;
3-49
-- ASCII sink
process
begin
loop
wait until rising_edge( Clk ) and DORdy = '1';
TxBusy <= '1';
wait for 11 * Tclk;
TxBusy <= '0';
-- e.g. 11 * Tclk
end loop;
end process;
end architecture;
3-50
25
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement