Post on 26-Jul-2018
6.11.2014
1
Computer System Structures
cz:Struktury počítačových systémů
Lecturer: Richard Šusta
ČVUT-FEL in Prague, CR – subject A0B35SPS
Version: 1.0
Registers, Counters,
and Dividers
VHL code similarities and differences
6.11.2014
2
SPS 3
1 bit Register
with Clear - Synchronous and Asynchronous
SCLRN
CLK
D
CLK
Q
CLRN
ACLRN
Power-up reset signal
1
1-bit register 0
MUX21
D
'0' Q
0
1
0 D
ENA
Q PRE
CLR
Q q~reg0
SCLRN
CLK
D
ACLRN
SPS 4
VHDL code of 1 bit register (1/3)
library ieee; use ieee.std_logic_1164.all;
entity reg is
port( CLK, D, SCLRN, ACLRN : in std_logic;
Q : out std_logic );
end;
architecture rtl of reg is
constant QCLR:std_logic:='0';
begin
process (CLK, ACLRN)
variable qv:std_logic;
begin
if ACLRN='0' then qv:=QCLR;
elsif rising_edge(CLK) then
if SCLRN='0' then qv:=QCLR; else qv:=D;
end if;
end if;
Q<=qv;
end process;
end rtl;
6.11.2014
3
SPS 5
VHDL code (2/3)
library ieee;use ieee.std_logic_1164.all;
entity reg is
port( CLK, D, SCLRN, ACLRN : in std_logic;
Q : out std_logic
);
end;
architecture rtl of reg is
constant QCLR:std_logic:='0';
begin
process (CLK, ACLRN) --- statements
end process;
end rtl;
L:Libraries
EP: entity-ports
AD: architecture declarations
EG: entity-generic -- generic ( list_of_generic_constants );
-- begin +statements executed in compile type or simulation EX: entity-passive process
AP: process concurrent statement
ACS: architecture
-concurrent statements -- next concurrent statements
SPS 6
process (CLK, ACLRN)
variable qv:std_logic;
begin
if ACLRN='0' then qv:=QCLR;
elsif rising_edge(CLK) then
if SCLRN='0' then qv:=QCLR; else qv:=D;
end if;
end if;
Q<=qv;
end process;
VHDL code - process statement (3/3)
PA: process-asynchronous inputs
PS: process
-synchronous part
PD:= process-dataflow part
PC: process-clock test
PD: process-declarations
PH: process-header with sensitivity list
6.11.2014
4
SPS 7
4 bit Register (1/3)
with Clear - Synchronous and Asynchronous
CLK
D[3..0]
CLK
Q[3..0]
CLRN
ACLRN
Power-up reset signal
SCLRN
1
4-bit register 0
MUX21
D
"0000" Q
4
4 4 4
D Q PRE
ENA
CLR
SEL DATAA
DATAB OUT0
MUX21
4' h0 --
qv~[3..0] SCLRN
D[3..0] Q[3..0]
qv[3..0]
ACLRN
CLK
SPS 8
4-bit register (2/3)
EP: Entity-ports
original: D : in std_logic;
Q : out std_logic;
new: D : in std_logic_vector(3 downto 0);
Q : out std_logic_vector(3 downto 0);
AD: Architecture declarations
original: constant QCLR : std_logic:='0';
new: constant QCLR : std_logic_vector(3 downto 0):="0000";
AD: Process declarations
original: variable qv:std_logic;
new: variable qv:std_logic_vector(3 downto 0);
…changes in code…
6.11.2014
5
SPS 9
4 bit register (3/3)
library ieee;use ieee.std_logic_1164.all; entity reg4 is port( CLK, SCLRN, ACLRN : in std_logic;
D : in std_logic_vector(3 downto 0); Q : out std_logic_vector(3 downto 0) ); end; architecture rtl of reg4 is
constant QCLR:std_logic_vector(3 downto 0):="0000"; begin process (CLK, ACLRN) variable qv:std_logic_vector(3 downto 0); begin if ACLRN='0' then qv:=QCLR; elsif rising_edge(CLK) then if SCLRN='0' then qv:=QCLR; else qv:=D; end if; end if; Q<=qv; end process; end rtl;
…full code…
SPS 10
Variable-width Register (1/3)
CLK
D[W-1..0]
CLK
Q[W-1..0]
CLRN
ACLRN
Power-up reset signal
SCLRN
1
W-bit register 0
D
0 Q
W
W W
W
0 constant is explained on next slide
6.11.2014
6
SPS 11
How to create variable-width 0 vector
Convert integer to variable 0 vector
Add into L: Libraries numeric conversions
use ieee.numeric_std.all;
Convert integer literal to vector
constant QCLR:std_logic_vector(WIDTH-1 downto 0)
:=std_logic_vector ( to_unsigned(0,WIDTH) ); (see 5th lecture, slides from 58 to 60)
Use others keyword
constant QCLR:std_logic_vector(WIDTH-1 downto 0):=(others=>'0');
OTHERS represents all possible values not already listed. In
general, the meaning of
(OTHERS => Value)
is to set each bit of the destination operand to Value.
SPS 12
Variable-width Register (2/3)
EG: Entity-generic
generic( WIDTH:natural:=4 );
EP: Entity-ports
original: D : in std_logic_vector(3 downto 0);
Q : out std_logic_vector(3 downto 0);
new: D : in std_logic_vector(WIDTH-1 downto 0);
Q : out std_logic_vector(WIDTH-1 downto 0);
AD: Architecture declaration
original: constant QCLR:std_logic_vector(3 downto 0):="0000";
new: constant QCLR:std_logic_vector(WIDTH-1 downto 0):=(others=>0);
AD: Process declarations
original: variable qv:std_logic_vector(3 downto 0);
new: variable qv:std_logic_vector(WIDTH-1 downto 0);
…changes in code…
6.11.2014
7
SPS 13
Variable-width Register (3/3)
library ieee; use ieee.std_logic_1164.all;
entity reg_width is
generic( WIDTH:natural:=4 );
port( CLK, SCLRN, ACLRN : in std_logic;
D : in std_logic_vector(WIDTH-1 downto 0);
Q : out std_logic_vector(WIDTH-1 downto 0) );
end;
architecture rtl of reg_width is
constant QCLR:std_logic_vector(WIDTH-1 downto 0):=( others=>'0' );
begin
process (CLK, ACLRN)
variable qv:std_logic_vector( WIDTH-1 downto 0 );
begin
if ACLRN='0' then qv:=QCLR;
elsif rising_edge(CLK) then
if SCLRN='0' then qv:=QCLR; else qv:=D;
end if;
end if;
Q<=qv;
end process;
end rtl;
…full code…
SPS 14
Circular Variable-width Shift Register (1/3) with Asynchronous Clear - Synchronous Load
SLOAD
CLK
ACLRN
Power-up reset
signal D[3]
Q[3]
D
CLK
Q
CLRN
1
1-bit register 0
MUX2
1
D
CLK
Q
CLRN
1
1-bit register 0
MUX2
1
D
CLK
Q
CLRN
1
1-bit register 0
MUX2
1
D
CLK
Q
CLRN
1
1-bit register 0
MUX2
1
D[2] D[1] D[0]
Q[2]
Q[1]
Q[0] 4 bit version
6.11.2014
8
SPS 15
Circular Variable-width Shift Register (2/3)
EP: Entity-ports
change: SCLRN input was renamed to SLOAD
PS: process-synchronous part
original: if SCLRN='0' then
qv:=QCLR;
else qv:=D;
end if;
new: if SLOAD='0' then
qv:=qv( WIDTH-2 downto 0) & qv(WIDTH-1);
else qv:=D;
end if;
…changes in code…
SPS 16
Circular Variable-width Shift Register(3/3)
library ieee; use ieee.std_logic_1164.all;
entity reg_width is
generic( WIDTH:natural:=4 );
port( CLK, SLOAD, ACLRN : in std_logic;
D : in std_logic_vector(WIDTH-1 downto 0);
Q : out std_logic_vector(WIDTH-1 downto 0) );
end;
architecture rtl of reg_width is
constant QCLR:std_logic_vector(WIDTH-1 downto 0):=( others=>'0' );
begin
process (CLK, ACLRN)
variable qv:std_logic_vector( WIDTH-1 downto 0 );
begin
if ACLRN='0' then qv:=QCLR;
elsif rising_edge(CLK) then
if SLOAD='0' then qv:=qv(WIDTH-2 downto 0) & qv(WIDTH-1); else qv:=D;
end if;
end if;
Q<=qv;
end process;
end rtl;
…full code…
6.11.2014
9
SPS 17
How to initialize variable-width shift
Problem: Set shift after power up to a non zero state.
Initial state=1 can be again accomplished by converting integer literal, but what about
states with 1 only in main scale bit?
Create initialization by association list with others keyword.
constant QCLR:std_logic_vector(WIDTH-1 downto 0)
:= (0=>'1', others=>'0'); -- 1 only in QCLR(0)
constant QCLR1:std_logic_vector(WIDTH-1 downto 0)
:= (WIDTH-1=>'1', others=>'0'); -- 1 only in QCLR(WIDTH-1)
constant QCLR2:std_logic_vector(WIDTH-1 downto 0)
:= (WIDTH-1=>'0', 1=>'0', others=>'1'); -- 0 in QCLR(WIDTH-1) and QCLR(1)
Association lists => provide the mapping between formal or local generics, ports, or
subprogram parameter names and local or actual names or expressions.
association_list ::= association_element { , association_element }
association_element ::= [formal_part =>] actual_part
(for details, see VHDL Reference Manual, page 4-31)
SPS 18
Variable Counter (1/3)
CLK
D[W-1..0]
CLK
Q[W-1..0]
CLRN
ACLRN
Power-up reset signal
SCLRN
1
1-bit register 0
0 Q
W
W W
W
+1
6.11.2014
10
SPS 19
Counter definition
1. Counters are typically defined by specifying
a width in bits
2. Counters send their states to outputs
=> Avoid integers requiring conversions. Use type unsigned
or signed from library ieee.numeric_std.all; for counting
variable, e.g.
variable qv:unsigned(WIDTH-1 downto 0);
binary counter can be incremented by
qv:=qv+1; -- because qv has fix bit-width
SPS 20
Modulo counter definition
2. Modulo counter
if qv<(CONST_MODULO-1) -- e.g if qv<9 -- for MOD 10
then qv:=qv+1;
else qv:=(others=>'0');
end if;
Never use increment by
qv:=(qv+1) mod CONST_MODULO;
e.g. qv:=(qv+1) mod 10;
note: Operator MOD (reminder after division) is difficult
synthesizable, the construction leads to inefficient designs
6.11.2014
11
SPS 21
Counter definition
If counter is defined by its numeric modulo, the conversion to
width in bits is clumsy
1. First, add usage library in L-Libraries section
USE ieee.math_real.all;
Library math_real ccontains function that are not
synthesizable, their usage is possible only for constants,
or in simulation.
2. Conversion can be performed by
integer(ceil(log2(real(MAXCOUNT-1))));
expression where MAXCOUNT represents desired
modulo with value known during compilation. The
operation returns width in bits.
SPS 22
Variable Counter (2/3)
L: Libraries - added numeric_std
use ieee.numeric_std.all;
EP: Entity-ports - - D input was removed
AD: Architecture declaration
original: constant QCLR:std_logic_vector(WIDTH-1 downto 0):=(others=>0);
new: constant QCLR:unsigned(WIDTH-1 downto 0):=(others=>0); AD: Process declarations
original: variable qv:std_logic_vector(WIDTH-1 downto 0);
new: variable qv:unsigned(WIDTH-1 downto 0); PS: process-synchronous part
original: if SCLRN='0' then qv:=QCLR; else qv := D; end if;
new: if SCLRN='0' then qv:=QCLR; else qv := qv+1; end if;
PD:= process-dataflow part
original: Q<=qv;
new: Q<=std_logic_vector(qv);
…changes in comparison to
variable-width register…
6.11.2014
12
SPS 23
Variable Counter (3/3)
library ieee;use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity counter_width is generic(WIDTH:natural:=4); port( CLK, SCLRN, ACLRN : in std_logic; Q : out std_logic_vector(WIDTH-1 downto 0) ); end; architecture rtl of counter_width is constant QCLR:unsigned(WIDTH-1 downto 0):=(others=>'0'); begin process (CLK, ACLRN) variable qv:unsigned(WIDTH-1 downto 0); begin if ACLRN='0' then qv:=QCLR; elsif rising_edge(CLK) then if SCLRN='0' then qv:=QCLR; else qv := qv+1; end if; end if; Q<=std_logic_vector(qv); end process; end rtl;
…changes in comparision
to variable width register…
SPS 24 SPS 24
Example: Divider
with 50% duty cycle
6.11.2014
13
SPS 25
Synchronous Divider by 100
EP: entity ports CLK : in std_logic; q : out std_logic;
PS: process declarations
variable cnt : integer range 0 to 499:=0;
variable q2 : std_logic := '0';
PS: process synchronous part
if cnt<499 then cnt:=cnt+1;
else cnt:=0; q2:=not q2;
end if;
ACS: process synchronous part
q<=q2;
13 LE (10 reg)
SPS 26
Synchronous Divider
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;
entity FreqDivBy1000 is
port(CLK : in std_logic; q : out std_logic);
end entity;
architecture behav of FreqDivBy1000 is
begin
process (CLK)
variable cnt : integer range 0 to 499:=0;
variable q2 : std_logic := '0';
begin
if (CLK'event and CLK='1') then
if cnt<499 then cnt:=cnt+1;
else cnt:=0; q2:=not q2; end if;
end if;
q<=q2;
end process;
end behav;
6.11.2014
14
SPS 27
Synchronous Divider by 100
PS: process declarations
origin: variable cnt : integer range 0 to 499:=0;
new: variable cnt : integer:=0;
new2: variable cnt : integer;
PS: process synchronous part
origin: if cnt<499 then cnt:=cnt+1;
else cnt:=0; q2:=not q2; end if;
new: if cnt=499 then cnt:=0; q2:=not q2;
else cnt:=cnt+1; end if;
13 LE (10 reg)
13 LE (10 reg)
18 LE (10 reg)
44 LE (33 reg)
76 LE (33 reg)
SPS 28 SPS 28
Information • If we supply detailed information
about circuit limit VHDL compiler will create more optimal circuit – Is it required 32 bit cnt variable ? -> No
– Is it necessary perform equality comparison? -> No
6.11.2014
15
SPS 29
Use Integers with Great Care
Integers are scalars. They only have numeric values and different
representations from types based on synthesizable std_logic.
Synthesis tools generally create 32-bit wide resources for unconstrained
integers.
Integer variables should have known value for a simulator. Consider proper
initialization.
Requirement for synthesizable part of SPS projects: Use integers only for
constants or literals. Constrained integer can be used only for internal counters
that do not send their count values to outputs, e.g. for frequency dividers. For all
other case use std_logic types.
signal n, m: integer; --unconstrained integer
signal i: integer range -8 to 7; -- signed integer
signal j: integer range 0 to 31; --unsigned integer
variable count : integer range 0 to 128 := 0; -- constr.+ initialized
Q: How many bits will have these integer variables?
SPS 30
A' B' C' D' + A' B C' D + A B C D + A B' C D' A' B' D + A' C B C' D' + A C' + A B D'
AB 00 01 11 10
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
00
01
11
10 C
CD
A
D
B
K-map for F 1
AB 00 01 11 10
0 0 0 0
1 0 0 0
1 1 0 1
1 1 0 0
00
01
11
10 C
CD
A
D
B
K-map for F 2
AB 00 01 11 10
0 1 1 1
0 0 1 1
0 0 0 0
0 0 1 0
00
01
11
10 C
CD
A
D
B
K-map for F 3
Remeber Two-Level Simplification
F1 =
F2 =
F3 =
F1 = F2' . F3'
Equality is expensive operation
6.11.2014
16
SPS 31
+A[31..0]
B[31..0]
ADDER
D Q
PRE
ENA
CLR
<A[31..0]
B[31..0]
LESS_THAN
D
ENA
Q
PRE
CLR
SEL
DATAA
DATABOUT0
MUX21
32' h00000001 --
Add0
q2
CLK
qLessThan01' h0 --
31' h000001F3 --
cnt[31..0]
cnt~[31..0]
32' h00000000 --
SPS 32 SPS 32
Conclusion
By inserting detailed information about circuit behavior, we have 13LE/10Reg
compare to the worst case 76LE/33Reg
without supplying any knowledge.
6.11.2014
17
SPS 33
Universal divider 1/2
library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity FreqDivByEven is
generic( EVEN_DIV: integer := 1000 );
port(CLK : in std_logic;
q : out std_logic);
begin assert EVEN_DIV mod 2=0
report "FreqDivByEven requires EVEN divisor"
severity severity_level(error);
end entity;
to be continued on the next slide
L:Libraries
EP: entity-ports
EG: entity-generic
EX: entity-passive process
SPS 34
Universal divider 2/2
architecture behav of FreqDivByEven is
constant DIVISOR:integer := EVEN_DIV/2;
begin
process (CLK)
variable cnt : integer range 0 to DIVISOR-1:=0;
variable q2 : std_logic := '0';
begin
if (CLK'event and CLK='1') then
if DIVISOR>1 and cnt<DIVISOR-1 then cnt:=cnt+1;
else cnt:=0; q2:=not q2; end if;
end if;
q<=q2;
end process;
end behav;
AD: architecture declarations
PS: process
-synchronous part
PD:= process-dataflow part
PC: process-clock test
PD: process-declarations
PH: process-header with sensitivity list
6.11.2014
18
SPS 35
kom_vhdl : Morse Beacon EAEA...
EA = . .- = 010001011100
library ieee;use ieee.std_logic_1164.all; use ieee.numeric_std.all;
entity kom_vhdl is
port(counter : in std_logic_vector(3 downto 0);
m, stop : out std_logic);
end;
architecture dataflow of kom_vhdl is
signal index : unsigned(counter'RANGE);
constant data : string := "010001011100";
begin index <= unsigned(counter);
m <= '1' when data( to_integer(index) )='1' else '0';
stop <= '0' when index < ( data'LENGTH - 1 ) else '1';
end architecture dataflow;
M
Co
un
ter
0..11 STOP STOP
START
SPS 36
Morse Beacon EAEA 1/5
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all;
LIBRARY work;
ENTITY morsebeacon IS
PORT (CLOCK_50 : IN STD_LOGIC;
KEY : IN STD_LOGIC_VECTOR(0 to 0);
LEDG : OUT STD_LOGIC_VECTOR(3 downto 0);
LEDR : OUT STD_LOGIC_VECTOR(17 downto 0)
);
END morsebeacon;
ARCHITECTURE rtl OF morsebeacon IS
// definitions of architecture
END rtl;
6.11.2014
19
SPS 37
Morse Beacon EAEA 2/5
ARCHITECTURE rtl OF morsebeacon IS
COMPONENT kom_vhdl
PORT(counter : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
m, stop : OUT STD_LOGIC );
END COMPONENT;
COMPONENT freqdivbyeven
GENERIC (EVEN_DIV : INTEGER);
PORT(CLK : IN STD_LOGIC; q : OUT STD_LOGIC );
END COMPONENT;
SIGNAL div_output, kom_stop, kom_out : STD_LOGIC;
SIGNAL counter_in : STD_LOGIC_VECTOR(3 downto 0);
BEGIN
// definitions of architecture
END rtl;
Component versus Entity Declaration
component component _name
generic ( generic_declaration1;
generic_declaration2;
….
generic_declarationN
);
port ( port_declaration1;
port_declaration2;
…
port_declarationM) ;
end component [ component _name ];
entity component _name is
generic ( generic_declaration1;
generic_declaration2;
….
generic_declarationN
);
port ( port_declaration1;
port_declaration2;
…
port_declarationM) ;
end [ entity ] [ component _name];
In a VHDL code, a component declaration is included in the
declaration part of an architecture body
6.11.2014
20
SPS 39
Morse Beacon EAEA 3/5
BEGIN // definitions of architecture
b2v_inst1 : kom_vhdl
PORT MAP(counter => counter_in,
m => kom_out, stop => kom_stop);
b2v_inst2 : freqdivbyeven
GENERIC MAP(EVEN_DIV => 10000000 )
PORT MAP(CLK => CLOCK_50, q => div_output);
morse_cntr:process(div_output, KEY(0)) is
// definitions of counter process
end process morse_cntr;
shift:process(div_output) is
// definitions of shift process
end process shift;
Instantiating component
label: instantiated_unit
[ GENERIC MAP (association_list) ]
[ PORT MAP (association_list) ] ;
instantiated_unit ::=
[COMPONENT] component_name
| ENTITY entity_name [ (architecture_name) ]
| CONFIGURATION configuration_name
association_list ::= association_element { , association_element }
association_element ::= [ formal_part => ] actual_part
Once a component is declared, its instance can be created
inside the architecture body.
6.11.2014
21
Component instance
component_name specifies the component to be
used, and instance_label assigns the instance with
a unique label for identification.
The generic map portion assigns the actual values
to the generics. Note that there is no semicolon after
the generic map portion.
The port map portion specifies the connections (i.e.,
“association”) between the component’s ports (known
as formal signals) and the external signals (known as
actual signals).
The port-association term has the general format
port_name => signal_name
SPS 42
Morse Beacon EAEA 4/5
morse_cntr:process(div_output, KEY(0)) is
// definitions of counter process
variable cntr : unsigned(3 downto 0) := (others=>'0');
begin
if KEY(0) = '0' then cntr := (others=>'0');
elsif rising_edge(div_output) then
if kom_stop = '1' then cntr:=(others=>'0');
else cntr := cntr + 1;
end if;
end if;
counter_in<=std_logic_vector(cntr);
LEDG <=std_logic_vector(cntr);
end process morse_cntr;
6.11.2014
22
SPS 43
Morse Beacon EAEA 5/5
shift:process(div_output) is
variable leds : std_logic_vector(LEDR'range) := (others=>'0');
begin
if rising_edge(div_output) then
leds:= leds(LEDR'HIGH-1 downto 0) & kom_out;
end if;
LEDR<=leds;
end process shift;
Graphic/Memory Arrays
...and their addressing
6.11.2014
23
SPS 45
Reading/writing data matrices
direct addressing - e.g. 7 segment, CRT
shift registers - e.g. CCD
row/column - e.g. LCD, memories
SPS 46
Method-1:Direct addressing
e 0
e 5
e 6
e 4
e 2
e 1
e 3
1
2 4
5
0
3
6
Pixel are
connected
by direct
wires
6.11.2014
24
SPS 47
Method-1:Cathode Ray Tubes
Direct addressing by deflected electron bean
Vertical Deflection
Horizontal Deflection
Phosper
Grid
Cathode
SPS 48
Raster Scan
Active lines
Retrace lines
The beam is off during
retrace.
Horizontal - beam
returns to left edge
Vertical - beam returns to
upper left corner.
Interlaced monitor scans
odd lines in odd pictures
and even lines in even
pictures
deflection - cz:vychylování
CRT display
6.11.2014
25
SPS 49
Horizontal, Vertical Syncs
Horizontal
oscillator
Horizontal
amplifier
CRT
Horizontal Sync
Vertical oscillator Vertical amplifier
Vertical
Sync
Video amplifier
Video
Input
60 hz
15.75 Khz
Serialization by shift registers
D Q
C CLR
0
D Q
C CLR
1
D Q
C CLR
2
D Q
C CLR
3
CLK
ACLR
DIN QD
D Q
C CLR
3
D Q
C CLR
2
D Q
C CLR
1
D Q
C CLR
0
CLK
ACLR
DIN
QA QB QC QD
D Q
C CLR
3
D Q
C CLR
2
D Q
C CLR
1
D Q
C CLR
0
CLK
ACLR
L/S
A B C D
I0 I1 I0 I1 I0 I1 I0 I1
QD
DIN
Serial-In, Serial-Out
Parallel-In, Serial-Out
Serial-In, Parallel-Out
6.11.2014
26
SPS 51
Method-2:Shift Registers - CCD Readout 1/3
[Image source: Digital Photography Review]
SPS 52
Method-2:Shift Registers - CCD Readout 2/3
[Image source: Digital Photography Review]
6.11.2014
27
SPS 53
Method-2:Shift Registers - CCD Readout 3/3
[Image source: Digital Photography Review]
SPS 54
Method-3:Row-Column
[Picture from: LCDs conceptos, Sony]
e.g. LCD matrices, memories
6.11.2014
28
Video Graphic Array (VGA) Signal
Introduced by IBM 1987
SPS 56
VGA signal
Horizontal
Blanking
Interval
Horizontal
Blanking
Interval
Horizontal
Blanking
Interval
Horizontal
Blanking
Interval
Horizontal
Blanking
Interval
Horizontal
Blanking
Interval
Vertical
Blanking
Interval
Vertical
Blanking
Interval
6.11.2014
29
Video Graphic Array (VGA) Signal
porch
(from latin "porta" = gate)
Cz:krytý vchod, přístřešek,
veranda
ve video: front/back porch
přední/zadní doba
zatemnění - poskytuje čas
pro inicializaci
“front porch”
HSYNC
VSYNC - Vertical Synchronization- beginning of frames
Visible Image
Horizontal Synchronization
- beginning of rows
“back porch”
Introduced by IBM 1987
SPS 58
[dipl. práce
ČVUT-FEL:
Martin Štěpánek
6.11.2014
30
SPS 59
DE2 ADV7173
VGA H_SYNC VGA_HS
10-bit Red level VGA_R[9:0]
10-bit Green level VGA_G[9:0]
10-bit Blue level VGA_B[9:0]
VGA Clock VGA_CLK
VGA BLANK VGA_BLANK
VGA V_SYNC VGA_VS
VGA SYNC VGA_SYNC
SPS 60
Analog video / Digital monitor
[Image: DVI specifications reference]
6.11.2014
31
SPS 61
Analog video / Digital monitor
[Images: DVI specifications reference]
SPS 62
Single link DVI
[Images: DVI specifications reference]
6.11.2014
32
SPS 63
Single link DVI
[Images: DVI specifications reference]
SPS 64
Dual Link DVI
[Images: DVI specifications reference]
6.11.2014
33
SPS 65
DVI versus VGA
DVI-D
DVI-A <=> VGA
VGA/DVI-A CONVERTER
DVI-A
DVI-I p
ixe
ls a
re s
en
t a
s d
ot str
ea
ms p
ixels
are
se
nt a
s a
na
log
va
lue
s
SPS 66
DVI
ANALOG
DIGITAL
DVI-I / DVI-A DVI-D
DIGITAL
VGA
COMPATIBLE PART OF THE DVI-I SIGNAL IS THE SAME AS VGA
GROUND SIGNAL
6.11.2014
34
VGA Module for Moving Flag
SPS 68
VGA Synchr. Generator
Position
logic
Regis
ter
Flag
logic
Frequency
Divider
VGA_HS
VGA_SYNC
VGA_BLANK
VGA_VS
VGA_ CLK
25.175 MHz
row
clo
um
n
VGA_ CLK
50 MHz
27 MHz
x
y
x
y VGA_R
VGA_G
VGA_B
KEY, SW
VG
A_V
S (
~60 H
z)
Generator of VGA
synchonization
6.11.2014
35
We need VHDL codes register - to store x-y position of flag
during one frame
counters - to create VGA synchronization
signals
divider of frequency - to create 25.175
MHz and a signal cca from 1 to 50 Hz for
positionlogic
VGA Synchronization Generator
in VHDL
VGA Modes: http://tinyvga.com/vga-timing
Cz:Literatura: Jan Balcárek: Bakalářská práce, VUT Brno 2008
http://www.vutbr.cz/www_base/zav_prace_soubor_verejne.php?file_id=18649
6.11.2014
36
SPS 71
VGA Synchr. Generator
“horizontal front
porch”
VSYNC
Visible Image
“horizontal back
porch” “front
porch”
HSYNC
Visible Image
“back
porch” “vertical
front
porch”
“vertical
back
porch”
HSYNC
“vertical
front
porch”
Cycle of generator VGA timing
0 , 0
639
524
479
799
SPS 72
VGA Synchr. Generator 25,175 MHz
“front porch”
HSYNC
Visible Image
“back porch”
“vertical
back
porch”
“vertical
front
porch”
0 , 0
639
599
479
799
Column Visible
image
Back Porch H-Synchro front porch
Range 0..639 640..655 656..657 658..799
Length 640 16 96 48
VGA_BLANK 1 0 0 0
VGA_HS 1 1 0 1
Row Range Length VGA_BLANK VGA_VS
Visible
image
0..479 480 1 1
Back
Porch
480..512 33 0 1
V-
Synchro
513..514 2 0 0
Front
Porch
515..524 10 0 1
6.11.2014
37
SPS 73
VGA Synchr. Generator
VGA_HS
VGA_BLANK
VGA_VS
VGA_ CLK 25.175 MHz
yrow
xcolumn
VGA_ CLK
Čítač
0..799 0..HS_LENGTH-1
CLK
Čítač
0..524 0..VS_LENGTH-1
CLK
Komparátor
513..514
Komparátor
656..752
VGA_SYNC
Komparátor
>=480 or
>=640
CLK
DY[9..0]
D0
D1
D2
D3
DX[9..0]
registr
SPS 74
31.777 us = 31.47 kHz
6.11.2014
38
SPS 75
16.67 ms= 60 Hz
SPS 76
VGASynchro.vhd (1/5)
library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;
entity VGAsynchro is
port(
CLK_25MHz175: in std_logic; -- recommended 25.175 MHz
ACLRN : in std_logic; -- asynchronously initilize signal
-- ACLRN should be connected to PLL locked output
--- or if you do not use PLL to reset key, e.g. KEY[0] on DE2
yrow, xcolumn : out unsigned(9 downto 0); -- pixel index
VGA_CLK, -- copy of input clock frequency
VGA_BLANK, -- ='0' if non-visible part of picture
VGA_HS, -- ='0' if horizontal synchronization puls
VGA_VS, -- ='0' if vertical synchronization puls
VGA_SYNC: out std_logic -- ='0' if VGA_HS='0' or VGA_VS='0'
);
end VGAsynchro;
Entity-Ports
6.11.2014
39
SPS 77
VGASynchro.vhd (2/5)
process(CLK_25MHz175, ACLRN)
-- http://tinyvga.com/vga-timing/640x480@60Hz
-- timing supposes VGA_CLK frequency 25.175 MHz
constant VS_LINE_VISIBLE : integer := 480; -- visible rows constant VS_FRONT_PORCH : integer := 10;
constant VS_SYN_LINES : integer := 2;
--constant VS_BACK_PORCH : integer := 33; --not used
constant VS_LENGTH : integer := 525; -- total rows including hidden
constant HS_PIXEL_VISIBLE : integer := 640; --visible columns constant HS_FRONT_PORCH : integer := 16;
constant HS_SYN_PULS : integer := 96;
--constant HS_BACK_PORCH : integer := 48; --not used
constant HS_LENGTH : integer := 800; ---- total columns including hidden
variable xc: unsigned(xcolumn'range); -- horizontal counter, i.e. columns
variable yr: unsigned(yrow'range); --vertical counter, i.e. rows constant xyZERO : unsigned(xc'range) := (others=>'0');
variable qVGA_VS, qVGA_HS, qVGA_BLANK: std_logic;
begin
SPS 78
VGASynchro.vhd (3/5)
begin
if ACLRN='0' then
xc:=xyZERO; yr:=xyZERO;
qVGA_VS:='1'; qVGA_HS:='1'; qVGA_BLANK:='1';
VGA_SYNC<= qVGA_VS and qVGA_HS;
VGA_VS<=qVGA_VS; VGA_HS<=qVGA_HS;
VGA_BLANK<=qVGA_BLANK;
yrow<=yr; xcolumn<=xc;
elsif rising_edge(CLK_25MHz175) then
6.11.2014
40
SPS 79
VGASynchro.vhd (4/5)
elsif rising_edge(CLK_25MHz175) then
-- vertical synchronization puls
if (yr >= (VS_LINE_VISIBLE+VS_FRONT_PORCH))
and (yr < (VS_LINE_VISIBLE+VS_FRONT_PORCH+VS_SYN_LINES))
then qVGA_VS := '0'; else qVGA_VS := '1';
end if;
-- horizontal synchronization puls
if (xc >= (HS_PIXEL_VISIBLE+HS_FRONT_PORCH))
and (xc < (HS_PIXEL_VISIBLE+HS_FRONT_PORCH+HS_SYN_PULS))
then qVGA_HS :='0'; else qVGA_HS :='1';
end if;
-- '0' if non visible part of picture, otherwise '1'
if (xc < HS_PIXEL_VISIBLE) and (yr < VS_LINE_VISIBLE)
then qVGA_BLANK :='1';
else qVGA_BLANK :='0';
end if;
SPS 80
VGASynchro.vhd (5/5)
-- On rising edge of CLK_25MHz175 copy results to outputs ---
VGA_SYNC<= qVGA_VS and qVGA_HS;
VGA_VS<=qVGA_VS; VGA_HS<=qVGA_HS;
VGA_BLANK<=qVGA_BLANK;
yrow<=yr; xcolumn<=xc;
-- Increment counters for the next loop
if xc<HS_LENGTH-1 then xc:= xc+1;
else xc:=(others=>'0');
if yr<VS_LENGTH-1 then yr:=yr+1;
else yr:=(others=>'0'); end if;
end if; -- rising_edge(CLK_25MHz175)
end process;
VGA_CLK <= CLK_25MHz175; -- VGA_CLK is copy of CLK_25MHz175 input
end rtl;
6.11.2014
41
SPS 81
VGAExampleSWCircle
architecture rtl of VGAExampleSWCircle is
constant COLOR_ON : std_logic_vector(9 downto 0) := (others=>'1');
constant COLOR_OFF : std_logic_vector(9 downto 0) := (others=>'0');
constant ROW_HEIGHT : integer := 480; -- number of visible rows
constant COLUMN_WIDTH : integer := 640; -- number of visible columns
begin
frame:process(VGA_CLK_in)
variable R, G, B: std_logic_vector(9 downto 0);
variable x, y, x0, y0, radius : integer;
begin -- conversion to integer variables for avoiding overflow problems
x := to_integer(xcolumn); y:=to_integer(yrow);
x0 := to_integer(unsigned("0"& datain(5 downto 0)&"011"));
y0 := to_integer(unsigned("00"& datain(11 downto 6)&"11"));
radius := to_integer(unsigned("00"& datain(17 downto 12) & "11"));
if rising_edge(VGA_CLK_in) then
SPS 82
VGAExampleSWCircle
architecture rtl of VGAExampleSWCircle is
constant COLOR_ON : std_logic_vector(9 downto 0) := (others=>'1');
constant COLOR_OFF : std_logic_vector(9 downto 0) := (others=>'0');
constant ROW_HEIGHT : integer := 480; -- number of visible rows
constant COLUMN_WIDTH : integer := 640; -- number of visible columns
begin
frame:process(VGA_CLK_in)
variable R, G, B: std_logic_vector(9 downto 0);
variable x, y, x0, y0, radius : integer;
begin -- conversion to integer variables for avoiding overflow problems
x := to_integer(xcolumn); y:=to_integer(yrow);
x0 := to_integer(unsigned("0"& datain(5 downto 0)&"011"));
y0 := to_integer(unsigned("00"& datain(11 downto 6)&"11"));
radius := to_integer(unsigned("00"& datain(17 downto 12) & "11"));
if rising_edge(VGA_CLK_in) then
6.11.2014
42
SPS 83
VGAExampleSWCircle
if rising_edge(VGA_CLK_in) then
R:=COLOR_ON;G:=COLOR_ON;B:=COLOR_ON; --initilize color to white
if ((y-y0)*(y-y0)+(x-x0)*(x-x0)<radius*radius)
then
B := COLOR_OFF; R := COLOR_OFF; --circle is blue
end if;
-- Copy results to output on rising_edge.
VGA_R<=R; VGA_G<=G; VGA_B<=B;
VGA_BLANK<=VGA_BLANK_in; VGA_HS<=VGA_HS_in;
VGA_VS<=VGA_VS_in; VGA_SYNC<=VGA_SYNC_in;
tb_yrow<=yrow; tb_xcolumn<=xcolumn;
-----------------------------------------------------------------------------------------------
end if; -- rising_edge(VGA_CLK_in)
-- No delay is necessary - it is periodical clock
VGA_CLK<=VGA_CLK_in;
end process;
end architecture rtl;
Overclocking Clocks
http://www.beige-box.com/
6.11.2014
43
Q(Quality) - Resonant curve
cz:Rezonanční křivka Pmax
Pmax
2 Δf
f0
Q = f0 / Δf
Q=5
Q=4
Q=3
Q=2
Crystal Oscillator
Working Range 50kHz - 80 MHz
- but high frequencies can be based on high overtones!
Temperature Coefficient k=10 [Hz/MHz/C], f = k f0 T (C)
High Q (1000 – 10,000)
Slow startup 5-20 ms in MHz range, seconds in kilohertz range
Time
X
6.11.2014
44
DE2
50 MHz
27 MHz
DE oscillators
CLOCK_27 - 27 MHz clock input ( with TD_RESET <= '1'; )
CLOCK_50 - 50 MHz clock input
6.11.2014
45
Phase Shift and Detector
clock1
clock2
clock1
clock2
clock1
clock2
+phase
-phase
+phase
-phase
DFF
CK
FB
R
D
CK
Q VDD
REF
D Q VDD
Reset
GoFaster
GoSlower
Charge
Pump
Icp
Icp
Sup
Sdn R
Eng: Charge pump has 2 strictly different meanings it is a part of phase detector in PLL and also a DC converter (cz:kaskádní násobič)
Phase Detector with Charge Pump
6.11.2014
46
Digital VCO Implementation
M1 M2
Vo+ V
o-
Vtune
I1
...
...
I2
IN
Vo
-
4W/L
4C
2W/L
2C
1W/L
C
B2 B1 B0B3
8C
8W/L
Vtune
Vdd
Tail current is digitally controlled (for amplitude calibration)
Cap array size increased (L decreased) to improve tuning range
Inversion-mode MOS varactor
No charge pump: Phase detector -> Up/Down Counter
Basic Block Diagram
reference
clock
PLL
ouput
clock
1/P
output
clock
fR
fL fO
fL/M = fR/N
fL= fR * (M/N)
fo= fR * (M/(N * P))
6.11.2014
47
PLL 27 MHz -> 25,175 Mhz
25,175MHz
25,2 MHz -> error < 0.1%
25MHz -> error = -0.7%
27MHz crystal:
10[Hz/C/MHz] *27[MHz]
* 60[dCo<-20-80Co] =+/-0,06%