Basic Codes Practice
Basic Codes Practice
Daniel Llamocca
✓ COMBINATIONAL CIRCUITS
▪ In combinational circuits, the output only
depends upon the present input values. COMBINATIONAL CIRCUIT
Combination
▪ The content of those storage elements al Logic
represents the circuit state. When the
circuit inputs change, it can be that the
circuit stays in certain state or changes to a Storage
different one. Over time, the circuit goes elements
through a sequence of states as a result of
a change in the inputs. The circuits with
this behavior are called sequential circuits.
Daniel Llamocca
✓SEQUENTIAL CIRCUITS
▪ Combinational circuits can be described with concurrent
statements or behavioral statements.
▪ Sequential circuits are best described with sequential
statements.
▪ Sequential circuits can either be asynchronous or
synchronous. In VHDL, they are described with
asynchronous/synchronous processes.
✓ Basic asynchronous sequential circuits: Latches
✓ Basic synchronous sequential circuits: flip flops,
counters, and registers.
Daniel Llamocca
✓ ASYNCHRONOUS PROCESS:
▪ SR Latch
▪ An SR Latch based on NOR gates:
S R Qt+1 Qt+1
R
Q 0 0 Qt Qt
0 1 0 1
1 0 1 0
S Q
1 1 0 0 restricted
▪ According to its truth table, the output can be assigned to
either ‘0’ or ‘1’. This circuit state (‘0’ or ‘1’) is stored in the
circuit when S=R=‘0’.
▪ FPGAs usually have trouble implementing these circuits as
FPGAs are synchronous circuits.
Daniel Llamocca
library ieee;
▪ SR Latch: VHDL code use ieee.std_logic_1164.all;
entity latch_sr is
port ( s,r: in std_logic;
S Q q, qn: out std_logic);
end latch_sr;
clock Edge E
Detector
S' Q
or S
Daniel Llamocca
✓ SYNCHRONOUS PROCESSES
Flip Flops:
▪ The edge detector circuit generates E=‘1’ during the edge (rising or
falling). We will work with circuits activated by either rising or falling
edge. We will not work with circuits activated by both edges.
▪ An example of a circuit that detects a rising edge is shown below. The
redundant NOT gates cause a delay that allows a pulse to be generated
during a rising edge (or positive edge).
clock
E
sig
clock
sig
E
Daniel Llamocca
✓ SYNCHRONOUS PROCESSES
library ieee;
▪ SR Flip Flop use ieee.std_logic_1164.all;
entity ff_sr is
S Q S Q port ( s,r, clock: in std_logic;
clock clock
q, qn: out std_logic);
end ff_sr;
Q Q
R R
Positive Negative architecture bhv of ff_sr is
edge-triggered edge-triggered signal qt,qnt: std_logic;
begin
process (s,r,clock)
begin
Positive-edge triggered if (clock'event and clock='1') then
Negative-edge triggered --if (clock'event and clock='0') then
R if s='1' and r='0' then
qt<='1'; qnt<='0';
Q
elsif s='0' and r='1' then
clock Edge E qt<='0'; qnt <='1';
Detector
elsif s='1' and r='1' then
Q qt<='0'; qnt <= '0';
S
end if;
end if;
end process;
q <= qt; qn <= qnt;
end bhv;
Daniel Llamocca
✓ SYNCHRONOUS PROCESSES
library ieee;
▪ D Flip Flop use ieee.std_logic_1164.all;
entity ff_d is
port ( d, clock: in std_logic;
D Q
q, qn: out std_logic);
end ff_d;
clock
Q architecture bhv of ff_d is
signal qt,qnt: std_logic;
begin
clock D Qt+1 process (d,clock)
begin
0 0 if (clock'event and clock='1') then
qt<=d;
1 1 end if;
end process;
q <= qt; qn <= not(qt);
D end bhv;
Q
* Note: Signal qt is needed.
clock Edge E
In VHDL, we cannot feedback
Detector an output (in this case q) as an
Q input of the circuit
Daniel Llamocca
✓ SYNCHRONOUS PROCESSES
▪ T Flip Flop
library ieee;
use ieee.std_logic_1164.all;
entity ff_jk is
J Q port ( s,r, clock: in std_logic;
q, qn: out std_logic);
clock end ff_jk;
▪ Register types:
▪ Simple Register (with/without enable)
▪ Shift register (with/without enable)
Serial input, parallel output
Serial input, serial output
▪ Parallel access shift register (parallel/serial input,
parallel/serial output).
Daniel Llamocca
✓ PARALLEL LOAD, PARALLEL OUTPUT
▪ 8-bit register with enable and
asynchronous library ieee;
reset use ieee.std_logic_1164.all;
entity reg8 is
port (clock, resetn, E: in std_logic;
D: in std_logic_vector (7 downto 0);
Q: out std_logic_vector (7 downto 0));
end reg8;
OLUT
hexadecimals converted
LUT 0 0 F 0 8 6
clk 6-to-6 0 0 F E 9 5
in this direction
E
0 C 3 3 3 A
0 F 0 8 7 6
0 F 0 F E D
OE 0 F F 0 C A
...
0 F F E 9 5
C 3 3 3 3 B
clk
F 0 0 8 7 6
F 0 0 F E 9
resetn F 0 F 0 C 2
F 0 F E 9 5
F C 3 3 3 A
OE F F 0 8 6 5
63
DATA 110001 101001 100111 100001 000111 000111 100001 011100
data5
data4
data3
data2
data1
data0
DI 110001 100111 000111 100001
Daniel Llamocca
✓ REGISTER: Example
▪ 3-state buffers and 6-to-6 LUT
▪ Data: 64 rows of 6 bits. Or 6 columns of 64 bits. The figure shows
the entity VHDL portion of the system.
entity sysLUT6to6 is
generic( data5: std_logic_vector(63 downto 0):=x"ffffffc000000000";
data4: std_logic_vector(63 downto 0):=x"fc00003ffffc0000";
data3: std_logic_vector(63 downto 0):=x"03ff003ff003ff00";
data2: std_logic_vector(63 downto 0):=x"83e0f83e0f83e0f0";
data1: std_logic_vector(63 downto 0):=x"639ce739ce7398cc";
data0: std_logic_vector(63 downto 0):=x"5a5296b5ad6a56aa");
port (clk, resetn, OE: in std_logic;
data: inout std_logic_vector (5 downto 0));
end sysLUT6to6;
▪ Testbench: The code shows that when DATA is output (OE=0), it
MUST be assigned the value ‘Z’. ➢ sysLUT6to6.zip:
... sysLUT6to6.vhd,
resetn<='0'; DATA<="ZZZZZZ";wait for 100 ns; my6to6LUT.vhd,
resetn<='1'; wait for T; my6to1LUT.vhd,
OE<='1'; DATA<="110001";wait for 2*T; my5to1LUT.vhd,
OE<='0'; DATA<="ZZZZZZ";wait for 2*T; my4to1LUT.vhd,
OE<='1'; DATA<="100111";wait for 2*T; my_rege.vhd,
OE<='0'; DATA<="ZZZZZZ";wait for 2*T;
tb_sysLUT6to6.vhd
Daniel Llamocca
✓ SHIFT REGISTER: Serial Input,
Serial/ Parallel Output
▪ n-bit right shift register:
Qn-1 Qn-2 Qn-3 Q0
resetn
clk
clk
PARAMETRIC CODE:
➢ my_shiftreg.zip: Generic n-bit left/right Shift Register
my_shiftreg.vhd,
tb_my_shiftreg.vhd
Daniel Llamocca
✓ PARALLEL ACCESS SHIFT REGISTER
▪ 4-bit right parallel access shift register with enable:
Q3 Q2 Q1 Q0
resetn
D Q D Q D Q D Q
E E E E E
clk
0 1 0 1 0 1 0 1
din D3 s_l D2 D1 D0
resetn
D Q D Q D Q D Q
E E E E E
clk
0 1 0 1 0 1 0 1
din D0 s_l D1 D2 D3
PARAMETRIC CODE:
➢ my_pashiftreg.zip: Generic n-bit left/right Parallel Access Shift Register
my_pashiftreg.vhd, tb_my_pashiftreg.vhd
Daniel Llamocca
✓ PARALLEL ACCESS
SHIFT REGISTER library ieee;
use ieee.std_logic_1164.all;
▪ Parallel/serial load entity pashreg4_right is
port (clock, resetn: in std_logic;
Parallel/serial output E, s_l, din: in std_logic;
Shift to the right, 4 bits dout: out std_logic;
D: in std_logic_vector (3 downto 0);
Q: out std_logic_vector (3 downto 0));
▪ s_l=1 -> Paralled load end pashreg4_right;
s_l=0 -> Serial load architecture bhv of pashreg4_right is
signal Qt: std_logic_vector (3 downto 0);
▪ ‘din’: serial input begin
process (resetn, clock, s_l, E)
▪ ‘D’: parallel input begin
▪ ‘dout’: serial output if resetn = '0' then Qt <= "0000";
elsif (clock'event and clock = '1') then
▪ ‘Q’: parallel output if E = '1' then
if s_l='1' then Qt <= D;
else
resetn Qt(0) <= Qt(1); Qt(1) <= Qt(2);
Qt(2) <= Qt(3); Qt(3) <= din;
D 4 D Q 4 end if;
E E end if;
dout
s_l s_l end if;
din din end process;
clock Q <= Qt; dout <= Qt(0);
end bhv;
Daniel Llamocca
✓ PARALLEL ACCESS
library ieee;
SHIFT REGISTER use ieee.std_logic_1164.all;
entity pashreg4_right is
▪ Parallel/serial load port (clock, resetn: in std_logic;
Parallel/serial output E, s_l, din: in std_logic;
dout: out std_logic;
Shift to the right, 4 bits D: in std_logic_vector (3 downto 0);
Q: out std_logic_vector (3 downto 0));
▪ Use of VHDL for loop end pashreg4_right;
▪ s_l=1 -> Parallel load architecture bhv of pashreg4_right is
s_l=0 -> Serial load signal Qt: std_logic_vector (3 downto 0);
begin
▪ ‘din’: serial input process (resetn, clock, s_l, E)
begin
▪ ‘D’: parallel input if resetn = '0' then Qt <= "0000";
elsif (clock'event and clock = '1') then
▪ ‘dout’: serial output if E = '1' then
if s_l='1' then Qt <= D;
▪ ‘Q’: parallel output else
gg: for i in 0 to 2 loop
resetn Qt(i) <= Qt(i+1);
end loop;
D 4 D Q 4 Qt(3) <= din;
E E dout
end if;
s_l s_l end if;
din din end if;
clock end process;
Q <= Qt; dout <= Qt(0);
Daniel Llamocca end bhv;
✓ PARALLEL ACCESS
SHIFT REGISTER library ieee;
use ieee.std_logic_1164.all;
▪ Parallel/serial load entity pashreg4_left is
Parallel/serial output port (clock, resetn: in std_logic;
E, s_l, din: in std_logic;
Shift to the left, 4 bits dout: out std_logic;
D: in std_logic_vector (3 downto 0);
Q: out std_logic_vector (3 downto 0));
▪ s_l=1 -> Paralled load end pashreg4_left;
s_l=0 -> Serial load architecture bhv of pashreg4_left is
▪ ‘din’: serial input signal Qt: std_logic_vector (3 downto 0);
begin
▪ ‘D’: parallel input process (resetn, clock, s_l, E)
begin
▪ ‘dout’: serial output if resetn = '0' then Qt <= "0000";
elsif (clock'event and clock = '1') then
▪ ‘Q’: parallel output if E = '1' then
if s_l='1' then Qt <= D;
else
resetn Qt(3) <= Qt(2); Qt(2) <= Qt(1);
Qt(1) <= Qt(0); Qt(0) <= din;
D 4 D Q 4 end if;
E E end if;
dout
s_l s_l end if;
din din
end process;
clock Q <= Qt; dout <= Qt(3);
Daniel Llamocca end bhv;
✓ PARALLEL ACCESS
SHIFT REGISTER
library ieee;
use ieee.std_logic_1164.all;
entity pashreg4_left is
▪ Parallel/serial load port (clock, resetn: in std_logic;
Parallel/serial output E, s_l, din: in std_logic;
dout: out std_logic;
Shift to the left, 4 bits D: in std_logic_vector (3 downto 0);
Q: out std_logic_vector (3 downto 0));
▪ Use of VHDL for loop end pashreg4_left;
▪ s_l=1 -> Parallel load architecture bhv of pashreg4_left is
s_l=0 -> Serial load signal Qt: std_logic_vector (3 downto 0);
begin
▪ ‘din’: serial input process (resetn, clock, s_l, E)
begin
▪ ‘D’: parallel input if resetn = '0' then Qt <= "0000";
elsif (clock'event and clock = '1') then
▪ ‘dout’: serial output if E = '1' then
if s_l='1' then Qt <= D;
▪ ‘Q’: parallel output else
gg: for i in 1 to 3 loop
resetn Qt(i) <= Qt(i-1);
end loop;
D 4 D Q 4 Qt(0) <= din;
E E end if;
dout
s_l s_l end if;
din din end if;
clock end process;
Q <= Qt; dout <= Qt(3);
Daniel Llamocca end bhv;
✓ SYNCHRONOUS PROCESSES
▪ Synchronous Counters
▪ Counters are very useful in digital systems. They can count the
number of occurrences of a certain event, generate time intervals for
task control, track elapsed time between two events, etc.
▪ Synchronous counters change their output on the clock edge (rising
or falling). Counters are made of flip flops and combinatorial logic.
Every flip flop in a synchronous counter shares the same clock
signal. The figure shows a 4-bit synchronous binary counter (0000
to 1111). A resetn signal is also included to initialize the count.
resetn
'1' T Q T Q T Q T Q
Qn Qn Qn Qn
clock
Q0 Q1 Q2 Q3
Daniel Llamocca
✓ 4-bit binary counter with asynchronous
active-low reset
▪ Count: 0 to 24-1 (once it gets to 24-1, it goes back to 0)
▪ resetn: active-low signal that sets Q to 0 as soon as it is 0, with no
regards to the clock library ieee;
use ieee.std_logic_1164.all;
▪ VHDL code: The
behavioral style is entity my_count4b is
preferred for counters port ( clock, resetn: in std_logic;
Q: out integer range 0 to 15);
(instead of the end my_count4b;
structural description).
architecture bhv of my_count4b is
▪ VHDL code: integer is signal Qt: integer range 0 to 15;
used instead of begin
std_logic_vector. The process (resetn,clock)
begin
number of bits (4) is if resetn = '0' then
automatically computed. Qt <= 0;
resetn elsif (clock'event and clock='1') then
Q 4 Qt <= Qt + 1;
end if;
clock end process;
binary counter Q <= Qt;
Daniel Llamocca 0 to 15 end bhv;
✓ 4-bit binary counter with enable and
asynchronous active-low reset
▪ Synchronous enable library ieee;
signal (‘E’): Only use ieee.std_logic_1164.all;
considered on the
entity my_count4b_E is
rising clock edge. port ( clock, resetn, E: in std_logic;
▪ This is also called a Q: out integer range 0 to 15);
end my_count4b_E;
counter modulo-15
▪ If Qt=1111, then architecture bhv of my_count4b_E is
signal Qt: integer range 0 to 15;
Qt Qt+1 results in begin
Qt=0000 (since for process (resetn,clock, E)
4 bits, 1111+1=0000) begin
if resetn = '0' then
This is true of any Qt <= 0;
binary counter (0 to 2 -1) elsif (clock'event and clock='1') then
n
resetn if E = '1' then
E Q 4 Qt <= Qt + 1;
E
end if;
end if;
clock end process;
Q <= Qt;
counter
modulo-15
end bhv;
Daniel Llamocca
✓ 4-bit binary counter with enable,
asynchronous active-low reset and
library ieee;
synchronous clear use ieee.std_logic_1164.all;
▪ The signals ‘E’ and
entity my_count4b_E_sclr is
‘sclr’ are synchronous, port ( clock, resetn, E, sclr: in std_logic;
thus they are only Q: out integer range 0 to 15);
end my_count4b_E_sclr;
considered on the
rising clock edge. architecture bhv of my_count4b_E_sclr is
signal Qt: integer range 0 to 15;
▪ If E=sclr=1 then Qt begin
is set to 0. process (resetn,clock, E)
begin
▪ When Qt = 15, if resetn = '0' then
then Qt Qt+1 will Qt <= 0;
elsif (clock'event and clock='1') then
result in Qt = 0. if E = '1' then
resetn if sclr = '1' then Qt <= 0;
else
Q 4
E E Qt <= Qt + 1;
sclr sclr end if;
end if;
clock
end if;
counter end process;
modulo-15 Q <= Qt;
Daniel Llamocca end bhv;
✓ BCD (or modulo-10) counter with
asynchronous active-low reset
▪ Count: 0 to 9 (4 bits) library ieee;
use ieee.std_logic_1164.all;
▪ When Qt = 9, then
Qt Qt+1 results in entity my_bcd_count is
port ( clock, resetn: in std_logic;
Qt = 0. Q: out integer range 0 to 15);
Note: This behavior end my_bcd_count;
(9 → 0) must be
architecture bhv of my_bcd_count is
explicitly specified. signal Qt: integer range 0 to 15;
▪ This is different from begin
process (resetn,clock)
the 0-to-15 counter, begin
where the behavior if resetn = '0' then
Qt <= 0;
(15 → 0) was implicit. elsif (clock'event and clock='1') then
if Qt = 9 then
resetn Qt <= 0;
else
4 Qt <= Qt + 1;
Q end if;
end if;
clock
end process;
Q <= Qt;
Daniel Llamocca
BCD counter end bhv;
✓ modulo-13 counter with enable and
asynchronous active-low reset
▪ Count: 0 to 12 (4 bits) library ieee;
use ieee.std_logic_1164.all;
▪ Output ‘z’: Asserted use ieee.std_logic_arith.all;
entity my_mod13count is
when count is 12. port ( clock, resetn, E: in std_logic;
Q: out std_logic_vector(3 downto 0);
z: out std_logic);
end my_mod13count;