VHDL
Libraries and Types
WHEN ELSE
WITH SELECT
PROCESS
IF-THEN-ELSIF-ELSE
CASE WHEN
FOR
Components
Testbenches and simulation
Updated: 17 October 2023.
References
• Diseño de Circuitos Digitales con VHDL Online
– Machado Sanchez, Borromeo López
– Dpto. Tecnología Electrónica Universidad Rey Juan Carlos
• Electrónica digital : aplicaciones y problemas con VHDL.
– Prentice Hall, Madrid [etc.] : 2002.
• Diseño de Sistemas Digitales con VHDL
– Pérez, Soto, Fernández
– Ed. Paraninfo, 2002
• Vhdl for Programmable Logic
– Kevin Skahill
– Cypress semiconductor
VHDL
• VHSIC Hardware Description Language
– Very High Speed Integrated Circuit
• Models and simulates from high level
descriptions to gates or flip-flops
• Concurrency support
• Synthesis
• Hierarchy design top-down or down-top
Hardware Description!!!!!
Pros
• “Rapid” Prototyping
• Strongly typed
• Independent of technology and methodology
• Normalized
• Documentation, design and simulation
• Reusability (IP cores)
Cons
• Committee driven language
• Strongly typed
• Not everything can be synthesised but can be
modelled and simulated
– Lack of portability across platforms
• Think it is HARDWARE!
Library, Entity, Architecture.
Libraries
• IEEE Libs
– STD_LOGIC_1164
– STD_LOGIC_UNSIGNED
– STD_LOGIC_SIGNED
– STD_LOGIC_ARITH
– NUMERIC_STD
• STD
– STANDARD
– TEXTIO
• WORK
-
TYPES
• Integer -MAXINT...MAXINT
• Natural 0...MAXINT
• Positive 1...MAXINT
• Real -MAXREAL...MAXREAL
• Boolean TRUE, FALSE
• Bit 0,1
• Bit_vector Bit array
• Character 256
• String Char array
• Time -MAXINT...MAXINT <unit>
– MAXINT = 231-1
– MAXREAL=1.0E38
USER TYPES
• User defined
• Subrange
• Array
• Record
TYPE StateMach IS (IDLE,S0,S1,S2);
TYPE fan IS RANGE 1 TO 20;
TYPE MemRAM IS ARRAY (0 to 255) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SUBTYPE Decade IS INTEGER RANGE 0 to 9;
TYPE LogicGateTiming IS
RECORD
PropTime: TIME;
SetUp: TIME;
Hold: TIME
END RECORD;
STD_LOGIC_1164
• STD_LOGIC
• STD_LOGIC_VECTOR
U
X
O
1
Uninitialized
Unknown. Impossible to determine this value/result.
Logic ‘0’
Logic ‘1’
Z
W
L
H
-
High impedance
Weak signal
Weak. Probably ‘0’
Weak. Probalby “1”
Don’t care
Defined: and, nand, or, nor, xor, xnor, not
What about +,-,*…?
SIGNAL SigVector : STD_LOGIC_VECTOR (7 downto 0);
SIGNAL Sig : STD_LOGIC;
More tan ‘0’ and ‘1’!!
Operators
• Arithmetic
+,-,*,/,**,mod,rem,abs (check for type)
• Relational
=,/=,>,>=,<,<=
• Logical
and, nand, or, nor, xor, xnor, not
• Shift
sll, srl,sla,sra,rol,ror
• Concatenate
&
OBJECTS
• CONSTANT
• SIGNAL (HW related)
• VARIABLES (Process, Function and Procedure)
• FILES
CONSTANT V37: STD_LOGIC_VECTOR (7 downto 0) := "01011010";
SIGNAL Addbus: STD_LOGIC_VECTOR(15 downto 0):= x"0000";
Addbus <= x"000“ & “1001”;
VARIABLE ctrT : INTEGER RANGE 0 TO 1000 := 800;
ctrT := 123;
USE std.textio.ALL;
TYPE t_sFile IS FILE OF STRING;
FILE InputFile: t_sFile OPEN READ_MODE IS "C:VHDLTUTOVectors.txt";
ENTITY
ENTITY <entity_name> IS
GENERIC (
<generic_name> : <type> := <value>;
<other generics>...
);
PORT (
<port_name> : <mode> <type>;
<other ports>...
);
END <entity_name>;
“Port” always!!!
MODE:
IN
OUT
INOUT
BUFFER
LINKAGE
ENTITY PARITY IS
GENERIC (
N : INTEGER := 8;
Delay : TIME := 10 ns);
PORT (
A : IN STD_LOGIC_VECTOR (N-1 downto 0) := (OTHERS =>'0');
ODD : OUT STD_LOGIC);
END PARITY;
ARCHITECTURE
ARCHITECTURE <arch_name> OF <entity_name> IS
-- declarative_items (
-- signal declarations,
-- component declarations,
-- etc.)
BEGIN
-- architecture body
END <arch_name>;
Component description!!!
DESCRIPTIONS
• Behavioural: High level or algorithmic
• Dataflow: RTL (register transfer level)
• Structural: Logic components
• Mixed
CONFIGURATIONS
ENT1
ARCH1
ARCH2
ENT2
ARCH1
ARCH2
WHEN...ELSE
<name> <= <expression> when <condition> else
<expression> when <condition> else
<expression>;
s <= "00" WHEN a = b ELSE
"01" WHEN a > b ELSE
"11";
s1 <= d1 WHEN control = '1' ELSE UNAFFECTED;
s2 <= d2 WHEN control = '1' ELSE s2;
s <= "00" WHEN (A='0' AND B='0' AND ENABLE ='1') ELSE
"01" WHEN (A='1' AND B='0' AND ENABLE ='1') ELSE
"01" WHEN (A='0' AND B='1' AND ENABLE ='1') ELSE
“10" WHEN (A='1' AND B='1' AND ENABLE ='1') ELSE
UNAFFECTED;
Conditional.
WITH...SELECT
WITH <choice_expression> SELECT
<name> <= <expression> WHEN <choices>,
<expression> WHEN <choices>,
<expression> WHEN OTHERS;
WITH w SELECT
F<= "0000001" WHEN "0000", --0
"1001111" WHEN "0001", --1
"0010010" WHEN "0010“, --2
"0000110" WHEN "0011",
"1001100" WHEN "0100",
"0100100" WHEN "0101",
"0100000" WHEN "0110",
"0001111" WHEN "0111",
"0000000" WHEN "1000",
"0000100" WHEN "1001",
"0000010" WHEN "1010",
"1100000" WHEN "1011",
"0110001" WHEN "1100",
"1000010" WHEN "1101",
"0010000" WHEN "1110",
"0111000" WHEN "1111";
Conditional.
WITH (ENABLE & A & B) SELECT
s <= "00" WHEN "000",
"01" WHEN "110" | "101",
"11" WHEN "111",
UNAFFECTED WHEN OTHERS;
PROCESS - WAIT
<label>:PROCESS (<all_input_signals_separated_by_commas>)
-- declarative_items
-- variable and constant declarations,
-- types or subtypes declarations
BEGIN
<statements>;
END PROCESS;
G: PROCESS
BEGIN
G0 <= '1' AFTER 5 ns,
'0' AFTER 10 ns,
'1' AFTER 15 ns,
'0' AFTER 20 ns;
G1 <= '1' AFTER 5 ns,
'0' AFTER 15 ns;
WAIT;
END PROCESS G;
G: PROCESS
BEGIN
WAIT FOR 5ns; --5ns
G0 <= '1'; G1 <= '1';
WAIT FOR 5ns; --10ns
G0 <= '0';
WAIT FOR 5ns; --15ns
G0 <= '1'; G1 <= '0';
WAIT FOR 5ns; --20ns
G0 <= '0';
WAIT;
END PROCESS G;
Sensitivity list!!! All the variables that, when
changed, need the process to be activated.
BIN_COMP : PROCESS
BEGIN
WAIT ON A, B, ENABLE;
. . .
END PROCESS;
BIN_COMP : PROCESS (A,B,ENABLE)
BEGIN
. . .
END PROCESS;
ENTITY example
PORT ( c: IN std_logic;
d: OUT std_logic);
END ENTITY;
ARCHITECTURE ex_arch OF example IS
SIGNAL a,b: std_logic;
BEGIN
PROCESS(c)
VARIABLE z: std_logic;
BEGIN
a<= c and b;--SIGNAL assignation: 'a' same value until reach end of the PROCESS
z:= a or c; --VARIABLES assignation: after evaluate this line z = a or c with
-- a = the value at the beginning of the PROCESS
END PROCESS;
END ARCHITECTURE;
PROCESS
-- A,B,C,X Variables
-- A=0, B=1, C=2, X=3
BEGIN
WAIT UNTIL CLK ='1';
A := B + C; --1+2
X := A + C; --3+2
A := X + C; --5+2
END PROCESS;
-- A = 7, X = 5
PROCESS
-- A,B,C,X SIGNALS
-- A=0, B=1, C=2, X=3
BEGIN
WAIT UNTIL CLK ='1';
A <= B + C; --1+2
X <= A + C; --0+2
A <= X + C; --3+2
END PROCESS;
-- A = 5, X = 2
Assignation.
All the variables change at
the same time!!!
XX <= IN;
OUT <= XX;
SIGNAL1 <= SIGNAL2.
IF-THEN-ELSIF-ELSE
IF <condition> THEN
<statement>;
ELSIF <condition> THEN
<statement>;
ELSE
<statement>;
END IF;
Conditional. Inside Process.
ARCHITECTURE dataflow OF First IS
SIGNAL inS : STD_LOGIC_VECTOR (1 DOWNTO 0);
BEGIN
prc: PROCESS (A,B,ENABLE)
VARIABLE AG: STD_LOGIC_VECTOR (2 downto 0);
BEGIN
AG := A & B & ENABLE;
IF AG = "000" THEN inS <= "00";
ELSIF (AG = "110" OR AG = "101") THEN inS <= "01" ;
ELSIF AG = "111" THEN inS <= "11";
ELSE inS <= inS;
END IF;
END PROCESS;
S <= inS;
END dataflow;
CASE-WHEN
CASE (<2-bit select>) IS
WHEN "00" =>
<statement>;
WHEN "01" =>
<statement>;
WHEN "10" =>
<statement>;
WHEN "11" =>
<statement>;
WHEN OTHERS =>
<statement>;
END CASE;
Conditional. Inside Process.
CASE a IS
WHEN 0 => B:=0;
WHEN 1 to 50 => B:=1;
WHEN 99 to 51 => B:=2;
WHEN OTHERS => B:=3;
END CASE;
CASE w IS
WHEN "0000" => F<= "0000001"; --0
WHEN "0001" => F<= "1001111"; --1
WHEN "0010" => F<= "0010010"; --2
WHEN "0011" => F<= "0000110";
WHEN "0100" => F<= "1001100";
WHEN "0101" => F<= "0100100";
WHEN "0110" => F<= "0100000";
WHEN "0111" => F<= "0001111";
WHEN "1000" => F<= "0000000";
WHEN "1001" => F<= "0000100";
WHEN "1010" => F<= "0000010";
WHEN "1011" => F<= "1100000";
WHEN "1100" => F<= "0110001";
WHEN "1101" => F<= "1000010";
WHEN "1110" => F<= "0010000";
WHEN "1111" => F<= "0111000";
ARCHITECTURE dataflow OF First IS
SIGNAL inS : STD_LOGIC_VECTOR (1 downto 0);
BEGIN
prc: PROCESS (A,B,ENABLE)
VARIABLE AG: STD_LOGIC_VECTOR (2 downto 0);
BEGIN
AG := A & B & ENABLE;
CASE AG IS
WHEN "000" => inS <= "00";
WHEN "110" | "101" => inS <= "01";
WHEN "111" => inS <= "11";
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
S <= inS;
END dataflow;
FOR LOOP
FOR <name> IN <lower_limit> TO <upper_limit> LOOP
<statement>;
<statement>;
END LOOP;
PROCESS (A)
VARIABLE TMP : STD_LOGIC;
BEGIN
TMP := '0';
FOR I IN A'LOW TO A'HIGH LOOP
TMP := TMP XOR A(I);
END LOOP;
ODD <= TMP;
END PROCESS;
• Support for synthesis
– the loop range is static (i.e. implies a definite number of iterations), unroll it and
– the loop contains no wait statements.
PROCESS (y)
VARIABLE power_N : INTEGER;
BEGIN
power_N := y;
FOR I IN N DOWNTO 2 LOOP
power_N := power_N * y;
END LOOP;
END PROCESS;
WHILE LOOP
WHILE <condition> LOOP
<statement>;
<statement>;
END LOOP;
PROCESS --Testbench clock generator
BEGIN
WHILE TRUE LOOP
CLK <= not CLK ;
WAIT FOR PERIOD/2;
END LOOP;
WAIT;
END PROCESS;
PROCESS (y)
VARIABLE I : INTEGER RANGE 0 TO 8 := 0;
VARIABLE power_N : INTEGER;
BEGIN
I := 0;
power_N := y;
WHILE I < N LOOP
power_N := power_N * y;
I := I + 1;
END LOOP;
END PROCESS;
EXIT NEXT
<label:> NEXT <loop_label:> <WHEN boolean_expr>;
<label:> EXIT <loop_label:> <WHEN boolean_expr>;
Loop_1: FOR count_value IN 1 TO 10 LOOP
EXIT Loop_1 WHEN reset = '1';
A_1: A(count_value) := '0';
END LOOP Loop_1;
A_2: B <= A AFTER 10 ns;
Loop_Z: FOR count_value IN 1 TO 8 LOOP
Assign_1: A(count_value) := '0';
NEXT WHEN condition_1;
Assign_2: A(count_value + 8) := '0';
END LOOP Loop_Z;
COMPONENTS
ARCHITECTURE MyArch OF MyEnt IS
--SIGNAL DECL
COMPONENT <component_name>
GENERIC (
<generic_name> : <type> := <value>;
<other generics>...
);
PORT (
<port_name> : <mode> <type>;
<other ports>...
);
END COMPONENT;
BEGIN
<instance_name> : <component_name>
GENERIC MAP (
<generic_name> => <value>,
<other generics>...
)
PORT MAP (
<port_name> => <signal_name>,
<other ports>...
);
SIMULATION - TESTBENCHES
ENTITY tb_adderN IS
END tb_adderN;
ARCHITECTURE behavior OF tb_adderN IS
CONSTANT NAd: INTEGER := 4;
COMPONENT adder_N
GENERIC( N : INTEGER);
PORT( a : IN std_logic_vector(NAd -1 downto 0);
b : IN std_logic_vector(NAd -1 downto 0);
cin : IN std_logic;
cout : OUT std_logic;
s : OUT std_logic_vector(NAd -1 downto 0)
);
END COMPONENT;
SIGNAL a : std_logic_vector(NAd -1 downto 0) := (others => '0');
SIGNAL b : std_logic_vector(NAd -1 downto 0) := (others => '0');
SIGNAL cin : std_logic := '0';
SIGNAL cout : std_logic;
SIGNAL s : std_logic_vector(NAd -1 downto 0);
BEGIN
uut: adder_N
GENERIC MAP (N => NAd)
PORT MAP (
a => a,
b => b,
cin => cin,
cout => cout,
s => s);
-- Stimulus process
stim_proc: PROCESS
BEGIN
WAIT FOR 1 us;
a <= "1111";
b <= "0001";
WAIT FOR 10 us;
a <= "0101";
b <= "0011";
WAIT FOR 10 us;
a <= "1001";
b <= "0101";
WAIT ;
END PROCESS;
END;
ARCHI________
CONSTANT clk_period : TIME := 10 ns;
BEGIN
-- Clock process definitions
clk_process :PROCESS
BEGIN
clk <= '0';
WAIT FOR clk_period/2;
clk <= '1';
WAIT FOR clk_period/2;
END PROCESS;
Combinational Circuits
• Data transmission
– Multiplexor (Mux)
– Demultiplexor (Demux)
• Code Converters
– Encoder
– Decoder
• Aritmetic & Logic
– Comparator
– Parity Generator/Checker
– Adder
COMBINATIONAL
CIRCUITS
I0
I1
Im
O0
O1
On
MUX
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY mux4_1 IS
PORT (s0 : IN STD_LOGIC;
s1 : IN STD_LOGIC;
in0 : IN STD_LOGIC;
in1 : IN STD_LOGIC;
in2 : IN STD_LOGIC;
in3 : IN STD_LOGIC;
output : OUT STD_LOGIC
);
END mux4_1;
http://www.quicknet.se/hdc/hdl/educaton/mux4_1/
ARCHITECTURE if_example OF mux4_1 IS
BEGIN
mux:PROCESS(s0, s1, in0, in1, in2, in3)
BEGIN
IF (s0='0' AND s1='0') THEN
output <= in0;
ELSIF (s0='1' AND s1='0') THEN
output <= in1;
ELSIF (s0='0' AND s1='1') THEN
output <= in2;
ELSIF (s0='1' AND s1='1') THEN
output <= in3;
ELSE -- (s0 or s1 are not 0 or 1)
output <= 'X';
END IF;
END PROCESS mux;
END if_example;
ARCHITECTURE case_example OF mux4_1 IS
BEGIN
mux:PROCESS(s0, s1, in0, in1, in2, in3)
VARIABLE sel : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
sel := s1 & s0; -- concatenate s1 and s0
CASE sel IS
WHEN "00" => output <= in0;
WHEN "01" => output <= in1;
WHEN "10" => output <= in2;
WHEN "11" => output <= in3;
WHEN OTHERS => output <= 'X';
END CASE;
END PROCESS mux;
END case_example;
ARCHITECTURE with_example OF mux4_1 IS
SIGNAL sel : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
sel <= s1 & s0; -- concatenate s1 and s0
WITH sel SELECT
output <= in0 WHEN "00",
in1 WHEN "01",
in2 WHEN "10",
in3 WHEN "11",
'X' WHEN OTHERS;
END with_example;
ARCHITECTURE when_example OF mux4_1 IS
BEGIN
output <= in0 WHEN (s1 & s0)="00" ELSE
in1 WHEN (s1 & s0)="01" ELSE
in2 WHEN (s1 & s0)="10" ELSE
in3 WHEN (s1 & s0)="11" ELSE
'X';
END when_example;
Demultiplexer
entity demux1a4 is
Port ( ENTRADA : in STD_LOGIC;
SEL : in STD_LOGIC_VECTOR (1 downto 0);
SALIDA : out STD_LOGIC_VECTOR (3 downto 0));
end demux1a4;
architecture Behavioral of demux1a4 is
begin
SALIDA <= "000" & ENTRADA WHEN SEL = "00" ELSE
"00" & ENTRADA & '0' WHEN SEL = "01" ELSE
'0' & ENTRADA & "00" WHEN SEL = "10" ELSE
ENTRADA & "000" WHEN SEL = "11" ELSE
"0000";
end Behavioral;
DEMUX
I
S1
O0
O1
O3
O2
S0
Encoder/Decoder
WITH w SELECT
F<= "0000001" WHEN "0000", --0
"1001111" WHEN "0001", --1
"0010010" WHEN "0010“, --2
"0000110" WHEN "0011",
"1001100" WHEN "0100",
"0100100" WHEN "0101",
"0100000" WHEN "0110",
"0001111" WHEN "0111",
"0000000" WHEN "1000",
"0000100" WHEN "1001",
"0000010" WHEN "1010", --A
"1100000" WHEN "1011",
"0110001" WHEN "1100",
"1000010" WHEN "1101",
"0010000" WHEN "1110",
"0111000" WHEN "1111"; --F
ENCODER
I0
I1
I2
n
O0
O1
On
DECODER
I0
I1
In
O0
O1
O2
n
binary to 7 Segment decoder
Comparator
entity comp_n is
generic (n: integer := 8);
Port ( A : in STD_LOGIC_VECTOR (n downto 0);
B : in STD_LOGIC_VECTOR (n downto 0);
EQ : out STD_LOGIC;
GT : out STD_LOGIC;
LT : out STD_LOGIC);
end comp_n;
architecture Behavioral of comp_n is
begin
PROCESS (A,B)
BEGIN
IF (A=B) THEN EQ <= '1'; ELSE EQ <= '0'; END IF;
END PROCESS;
PROCESS (A,B)
BEGIN
IF (A>B) THEN
GT <= '1';
ELSE
GT <= '0';
END IF;
END PROCESS;
PROCESS (A,B)
BEGIN
IF (A<B) THEN LT <= '1'; ELSE LT <= '0'; END IF;
END PROCESS;
end Behavioral;
COMPARATOR
A GT
EQ
LT
B
Half Adder
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY HalfAdder IS
Port ( a : IN STD_LOGIC;
b : IN STD_LOGIC;
s : OUT STD_LOGIC;
co : OUT STD_LOGIC);
END HalfAdder;
I1
I1
I2
I2
O
O
ENTITY AND_2 IS
GENERIC( PropDelay : TIME := 3 ns);
PORT( I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
O : OUT STD_LOGIC);
END AND_2;
ARCHITECTURE Behavioral OF AND_2 IS
BEGIN
O <= I1 AND I2 AFTER PropDelay;
END Behavioral;
ENTITY XOR_2 IS
GENERIC( PropDelay : TIME := 3 ns);
PORT( I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
O : OUT STD_LOGIC);
END XOR_2;
ARCHITECTURE Behavioral OF XOR_2 IS
BEGIN
O <= I1 XOR I2 AFTER PropDelay;
END Behavioral;
ARCHITECTURE Behavioral OF HalfAdder IS
COMPONENT XOR_2 IS
GENERIC( PropDelay : TIME := 3 ns);
PORT( I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
O : OUT STD_LOGIC);
END COMPONENT;
COMPONENT AND_2 IS
GENERIC( PropDelay : TIME := 3 ns);
PORT( I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
O : OUT STD_LOGIC);
END COMPONENT;
BEGIN
AND_GATE: AND_2
GENERIC MAP(PropDelay => 5 ns)
PORT MAP (
I1 => a,
I2 => b,
O => co);
XOR_GATE: XOR_2
GENERIC MAP(PropDelay => 5 ns)
PORT MAP (
I1 => a,
I2 => b,
O => s);
END Behavioral;
Full Adder
ARCHITECTURE Behavioral of FullAdder is
COMPONENT HalfAdder IS
PORT ( a : IN STD_LOGIC;
b : IN STD_LOGIC;
s : OUT STD_LOGIC;
co : OUT STD_LOGIC);
END COMPONENT;
SIGNAL P1,P2,P3 : STD_LOGIC;
BEGIN
HA1: HalfAdder
PORT MAP(
a => a,
b => b,
co => P2,
s => P1
);
HA2: HalfAdder
PORT MAP(
a => P1,
b => cin,
co => P3,
s => s
);
co <= P2 OR P3;
END Behavioral;
GENERATE
<label:> FOR parameter IN range GENERATE
<concurrent statements>
END GENERATE <label>;
<label:> IF <boolean_expr> GENERATE
<concurrent statements>
END GENERATE <label>;
ENTITY adder_N IS
GENERIC(
N : INTEGER := 8);
PORT ( a : IN STD_LOGIC_VECTOR (N-1 downto 0);
b : IN STD_LOGIC_VECTOR (N-1 downto 0);
cin : IN STD_LOGIC;
cout : OUT STD_LOGIC;
s : OUT STD_LOGIC_VECTOR (N-1 downto 0));
END adder_N;
ARCHITECTURE Behavioral OF adder_N IS
COMPONENT FullAdder IS
PORT ( a : In STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
s : OUT STD_LOGIC;
co : OUT STD_LOGIC);
END COMPONENT;
SIGNAL CARRIES: STD_LOGIC_VECTOR(N downto 1);
BEGIN
U0: FullAdder
PORT MAP(
a => a(0),
b => b(0),
cin => '0',
co => CARRIES(1),
s => s(0));
GenAdder_N: FOR I IN 1 TO N-1 GENERATE
Ux: FullAdder
PORT MAP(
a => a(I),
b => b(I),
cin => CARRIES(I),
co => CARRIES(I+1),
s => S(I));
END GENERATE;
cout <= CARRIES(N);
END Behavioral;
ARCHITECTURE Behavioral OF adder_N IS
COMPONENT FullAdder IS
PORT ( a : In STD_LOGIC;
b : IN STD_LOGIC;
cin : IN STD_LOGIC;
s : OUT STD_LOGIC;
co : OUT STD_LOGIC);
END COMPONENT;
SIGNAL CARRIES: STD_LOGIC_VECTOR(N downto 1);
BEGIN
GEN_ADD: FOR I IN 0 TO N-1 GENERATE
LOWER_BIT: IF I=0 GENERATE
U0: FullAdder PORT MAP
(a => A(I),
b => B(I),
cin => '0',
s => S(I),
co => CARRIES(I+1));
END GENERATE LOWER_BIT;
UPPER_BITS: IF I>0 GENERATE
UX: FullAdder PORT MAP
(a => A(I),
b => B(I),
cin => CARRIES(I),
s => S(I),
co => CARRIES(I+1));
END GENERATE UPPER_BITS;
END GENERATE GEN_ADD;
cout <= CARRIES(N);
END Behavioral;
Sequential circuits
• Registers (RS, JK, D, T)
• Counters
• Shift Registers
• States Machines
COMBINATIONAL
CIRCUITS
INPUTS OUTPUTS
COMBINATIONAL
CIRCUITS
MEMORY
CLK
Registers
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ffSimple IS
PORT ( clk : IN STD_LOGIC;
D : IN STD_LOGIC;
Q : OUT STD_LOGIC);
END ffSimple;
ARCHITECTURE Behavioral OF ffSimple IS
BEGIN
ff: PROCESS(clk)
BEGIN
IF(clk'event AND clk = '1') THEN
-- IF (rising_edge(clk)) THEN
Q <= D;
END IF;
END PROCESS;
END Behavioral;
Registers
• Asynchronous RESET
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ffAsyncRST IS
PORT ( clk : IN STD_LOGIC;
RST: IN STD_LOGIC;
D : IN STD_LOGIC;
Q : OUT STD_LOGIC);
END ffAsyncRST;
ARCHITECTURE Behavioral OF ffAsyncRST IS
BEGIN
ff: PROCESS(clk,RST)
BEGIN
IF RST = '1' THEN – Asynchronous RST
Q<= '0';
ELSIF(clk'event AND clk = '1') THEN
Q <= D;
END IF;
END PROCESS;
END Behavioral;
Registers
• Synchronous RESET
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ffSyncRST IS
PORT ( clk : IN STD_LOGIC;
RST: IN STD_LOGIC;
D : IN STD_LOGIC;
Q : OUT STD_LOGIC);
END ffSyncRST;
ARCHITECTURE Behavioral OF ffSyncRST IS
BEGIN
ff: PROCESS(clk) – No RST
BEGIN
IF (clk'event AND clk = '1') THEN
IF RST = '1' THEN -- Synchronous RST
Q<= '0';
ELSE
Q <= D;
END IF;
END IF;
END PROCESS;
END Behavioral;
Registers
ENTITY ffSelfInit IS
PORT ( clk : IN STD_LOGIC;
RST: IN STD_LOGIC;
D : IN STD_LOGIC;
Q : OUT STD_LOGIC := '0');
END ffSelfInit;
Registers
• Self Init when possible
• RESET better active high and synchronous
• RESET – SET – ENABLE
• Rising_edge
JK with CE
entity bies_jk is
Port ( clk : in STD_LOGIC;
j : in STD_LOGIC;
k : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
q : out STD_LOGIC;
qn : out STD_LOGIC);
end bies_jk;
architecture Behavioral of bies_jk is
signal in_q: std_logic := '0';
begin
process (clk)
begin
if rising_edge(clk) then
if rst='1' then
in_q <= '0';
elsif ce ='1' then
if (j='0' and k='0') then
in_q <= in_q;
elsif (j='0' and k='1') then
in_q <= '0';
elsif (j='1' and k='0') then
in_q <= '1';
elsif (j='1' and k='1') then
in_q <= not (in_q);
end if;
end if;
end if;
end process;
q <= in_q;
qn <= NOT in_q;
end Behavioral;
J
K
Q
Q
RST
ce
Counter
• More generic?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL; -- Vector Arithmetic
ENTITY counter IS
PORT(CLK, CLR : IN STD_LOGIC;
Q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END counter;
ARCHITECTURE archi OF counter IS
SIGNAL tmp: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS (CLK)
BEGIN
IF (CLK'event AND CLK='1') THEN
IF (CLR='1') THEN -- CLR Synchronous
tmp <= "0000";
ELSE
tmp <= tmp + 1; -- needs std_logic_unsigned
END IF;
END IF;
END PROCESS;
Q <= tmp;
END archi;
PWM
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.all; --STD_LOGIC_VECTOR to integer conversion
ENTITY PWM_N IS
PORT(
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
period : IN STD_LOGIC_VECTOR(7 DOWNTO 0) := "00001111";
Ton : IN STD_LOGIC_VECTOR(7 DOWNTO 0) := "00001000" ;
PWM_Out : OUT STD_LOGIC);
END PWM_N;
ARCHITECTURE Behavioral OF PWM_N IS
SIGNAL ctr_tmp : INTEGER := 0;
BEGIN
timer: PROCESS(clk)
BEGIN
IF(rising_edge(clk))THEN
IF(rst = '1') THEN
ctr_tmp <= 0;
ELSIF ctr_tmp = to_integer(unsigned(period)) then
ctr_tmp <= 0;
ELSE
ctr_tmp <= ctr_tmp + 1;
END IF;
END IF;
END PROCESS;
PWM_Out <= '1' WHEN ctr_tmp <= to_integer(unsigned(Ton)) ELSE '0';
--PWM_Out <= '1' WHEN ctr_tmp <= unsigned(Ton) ELSE '0'; --OK
END Behavioral;
Period<= “00001111” –16 clocks
Ton <= “00000011” – 4 clocks
• Clock domains
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity gatedClock is
Port ( clk : in STD_LOGIC;
slowClk1 : inout STD_LOGIC:= '0';
slowClk2 : inout STD_LOGIC:= '0');
end gatedClock;
architecture Behavioral of gatedClock is
signal tmpCounter1,tmpCounter2: integer :=0;
constant timeOut1:integer := 10;
constant timeOut2:integer := 4;
begin
Prescaler: process (clk)
begin
if(rising_edge(clk)) then
if (tmpCounter1 = timeOut1-1) then
tmpCounter1 <= 0;
else
tmpCounter1 <= tmpCounter1 + 1;
end if;
end if;
end process;
clk_Slow: process (clk)
Begin
if(rising_edge(clk)) then
if (tmpCounter1 < timeOut1/2) then
slowClk1 <= '0';
else
slowClk1 <= '1';
end if;
end if;
end process;
p_Clk1: process(slowClk1)
begin
if(rising_edge(slowClk1)) then
if (tmpCounter2 = timeOut2-1) then
tmpCounter2 <= 0;
else
tmpCounter2 <= tmpCounter2 + 1;
end if;
end if;
end process;
clk2_Slow: process (slowClk1)
Begin
if(rising_edge(slowClk1)) then
if (tmpCounter2 < timeOut2/2) then
slowClk2 <= '0';
else
slowClk2 <= '1';
end if;
end if;
end process;
end Behavioral;
GATED CLOCK!!
• Chip enable
Timer mod
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY timer IS
GENERIC(
TimeOut_ms : INTEGER := 10;
FrecCLK_MHz : INTEGER := 100);
PORT(CLK, CLR : IN STD_LOGIC;
Q : OUT STD_LOGIC := '0');
END timer;
ARCHITECTURE archi OF timer IS
SIGNAL ctr_time: INTEGER := 0;
CONSTANT TimeOut : INTEGER :=(TimeOut_ms*1000*FrecCLK_MHz) - 1;
BEGIN
PROCESS (CLK, CLR)
BEGIN
IF (CLR='1') THEN
ctr_time <= 0; -- CLR Asynchronous
ELSIF (CLK'event AND CLK='1') THEN
IF ctr_time = TimeOut THEN
ctr_time <= 0;
ELSE
ctr_time <= ctr_time + 1;
END IF;
END IF;
END PROCESS;
Q <= '1' WHEN ctr_time = TimeOut ELSE '0';
END archi;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ClockDivider is
Generic (Period_ms: integer := 2);
Port ( clk : in STD_LOGIC;
clkout : out STD_LOGIC);
end ClockDivider;
architecture Behavioral of ClockDivider is
COMPONENT timer IS
GENERIC(
TimeOut_ms : INTEGER := 10;
FrecCLK_MHz : INTEGER := 100);
PORT(CLK, CLR : IN STD_LOGIC;
Q : OUT STD_LOGIC := '0');
END COMPONENT;
signal inClk : std_Logic := '0';
signal ENABLE : std_logic := '0';
begin
Prescaler: timer
GENERIC MAP(
TimeOut_ms => Period_ms/2,FrecCLK_MHz => 100)
PORT MAP(
clk => clk, clr => '0‘, Q => ENABLE);
process(clk)
begin
if(rising_edge(clk)) then
if(ENABLE = '1') then
inClk <= not inClk;
end if;
end if;
end process;
clkout <= inClk ;
end Behavioral;
Shift Register
Shift Register
ENTITY ShiftReg_N IS
GENERIC (
N : INTEGER := 8);
PORT (
DATA_IN: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
INPUT : IN STD_LOGIC;
CLK : IN STD_LOGIC;
RST: IN STD_LOGIC;
LOAD_ENABLE: IN STD_LOGIC;
OUTPUT: OUT STD_LOGIC);
END ShiftReg_N;
ARCHITECTURE Behavioral OF ShiftReg_N IS
SIGNAL tmp : STD_LOGIC_VECTOR (N-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
PROCESS (CLK)
BEGIN
IF CLK'event AND CLK='1' THEN
IF RST ='1' THEN
tmp <= (others => '0');
ELSIF LOAD_ENABLE = '1' THEN
tmp <= DATA_IN;
ELSE
tmp <= INPUT & tmp(N-1 downto 1) ;
END IF;
END IF;
END PROCESS;
OUTPUT <= tmp(0);
END Behavioral; FOR?
CRC
CAN bus generator polynomial
Each flipflop represents a single CRC output bit.
The leftmost flipflop is the MSB of the CRC
http://www.ghsi.de/pages/subpages/Online%20CRC%20Calculation/
G(x) = x15+ x14+ x10+ x8+ x7+ x4+ x3+ x0
CRC-CAN
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CAN_CRC15_GEN is
Port ( DATA_IN : in STD_LOGIC;
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
ENABLE : in STD_LOGIC;
CRC_O : out STD_LOGIC_VECTOR (14 downto 0));
end CAN_CRC15_GEN;
architecture Behavioral of CAN_CRC15_GEN is
SIGNAL crc_tmp : STD_LOGIC_VECTOR (14 DOWNTO 0) := (OTHERS => '0');
SIGNAL SINV : STD_LOGIC := '0';
begin
SINV <= DATA_IN XOR crc_tmp(14);
PROCESS (CLK)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
IF(RESET='1') THEN
crc_tmp <= (OTHERS => '0');
ELSIF ENABLE = '1' THEN
crc_tmp(0) <= SINV;
crc_tmp(1) <= crc_tmp(0);
crc_tmp(2) <= crc_tmp(1);
crc_tmp(3) <= crc_tmp(2) XOR SINV;
crc_tmp(4) <= crc_tmp(3) XOR SINV;
crc_tmp(5) <= crc_tmp(4);
crc_tmp(6) <= crc_tmp(5);
crc_tmp(7) <= crc_tmp(6) XOR SINV;
crc_tmp(8) <= crc_tmp(7) XOR SINV;
crc_tmp(9) <= crc_tmp(8);
crc_tmp(10) <= crc_tmp(9) XOR SINV;
crc_tmp(11) <= crc_tmp(10);
crc_tmp(12) <= crc_tmp(11);
crc_tmp(13) <= crc_tmp(12);
crc_tmp(14) <= crc_tmp(13) XOR SINV;
END IF;
END IF;
END PROCESS;
CRC_O <= crc_tmp;
end Behavioral;
CRC
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
SHT85
Functions
• std_logic_arith (std_logic_unsigned,
std_logic_signed)
– Arithmetic functions (+,-,<,>) for STD_LOGIC,
STD_LOGIC_VECTOR and INTEGER
• numeric_std
– Arithmetic functions for SIGNED, UNSIGNED and
INTEGER but NOT for STD_LOGIC
• Operated SIGNALS and VARIABLES should be declared
as such.
– numeric_std preferred.
numeric_std translation functions
From To Funtion
SLV, UNSIGNED SIGNED SIGNED(From)
SIGNED,SLV UNSIGNED UNSIGNED(From)
UNSIGNED, SIGNED SLV STD_LOGIC_VECTOR(From)
UNSIGNED, SIGNED INTEGER TO_INTEGER(From)
NATURAL (INTEGER) UNSIGNED TO_UNSIGNED(From,SIZE)
INTEGER SIGNED TO_SIGNED(From,SIZE)
TYPE UNSIGNED IS ARRAY (NATURAL range <>) of STD_LOGIC;
TYPE SIGNED IS ARRAY (NATURAL range <>) of STD_LOGIC;
Counter with LOAD
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- preferred
-- entity declaration
entity counter_load is
port (
-- clock, reset ports
clock : in std_logic;
reset : in std_logic;
-- control ports
load : in std_logic;
-- input ports
initial_value : in std_logic_vector(3 downto 0);
-- output ports
count : out std_logic_vector(3 downto 0)
) ;
end counter_load;
-- architecture declaration
architecture counter_load_beh of counter_load is
signal count_i: unsigned(3 downto 0);
-- architecture body
begin
count_proc: process(clock, reset)
begin
if(reset='0') then
count_i <= (others => '0');
elsif(rising_edge(clock)) then
if (load = '1') then
count_i <= unsigned(initial_value);
else
count_i <= count_i + 1;
end if;
end if;
end process count_proc;
count <= std_logic_vector(count_i);
end architecture counter_load_beh;
-- architecture declaration
architecture counter_ud_beh of counter_load is
signal count_i: integer range 0 to 15;
-- architecture body
begin
count_proc: process(clock, reset)
begin
if(reset='0') then
count_i <= 0;
elsif(rising_edge(clock)) then
if(load = '1') then
count_i <= to_integer(unsigned(initial_value));
else
count_i <= count_i + 1;
end if;
end if;
end process count_proc;
count <= std_logic_vector(to_unsigned(count_i,4));
end architecture counter_ud_beh;
PWM 4 steps
COUNTER
MOD ‘M’
MUX 4 : 1
PWM_0
PWM_1
PWM_2
PWM_3
THRESHOLD
TIMER
PWM_Out_i
COMPARATOR PWM_Ou
S0
S1
CLK
RST
ENABLE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity PWM_CuatroNiveles is
Port ( rst : in STD_LOGIC;
clk : in STD_LOGIC;
S : in STD_LOGIC_VECTOR (1 downto 0);
enable : in STD_LOGIC;
PWM_Out : out STD_LOGIC);
end PWM_CuatroNiveles;
architecture Behavioral of PWM_CUatroNiveles is
-- TODO: Definir el número de pulsos que hay que contar para que transcurra el tiempo indicado si
-- cada ciclo de reloj es de 10 ns (100 MHz)
constant PWM_0: integer := CALCULAR; --4 ms
constant PWM_1: integer := CALCULAR; --8 ms
constant PWM_2: integer := CALCULAR; --12 ms
constant PWM_3: integer := CALCULAR; --16 ms
constant modulo_timer: integer := PWM_3;
signal timer:integer := 0;
signal threshold:integer;
signal PWM_Out_i: STD_LOGIC;
begin
-- TODO: Contador con reset síncrono a nivel alto y de módulo modulo_timer
-- Señal de contaje: timer
-- Inputs: clk, rst
-- Módulo: modulo_timer
contador_temporizador:
--TODO: Multiplexor 4 a 1
-- Inputs: PWM_0,PWM_1,PWM_2,PWM_3
-- Output: Threshold
-- Selección: S
mux:
-- TODO: Comparador de menor igual
-- Inputs: Timer, Threshold
-- Output: PWM_OUT_i
-- TODO: Salida con puerta lógica AND
-- Inputs: PWM_Out_i, rst, enable
-- Output: PWM_Out
Salida:
end Behavioral;
.XDC
• ## Clock signal
• set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }];
• create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
• ##Switches
• set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { S[0] }];
• set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { S[1] }];
• set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { enable }];
• set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { rst }];
• ## LEDs
• set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { PWM_Out }];
PWM MOD 16
1 ms step PWM
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.all; -- STD_LOGIC_VECTOR TO INTEGER
ENTITY PWM_Mod16 IS
PORT(
clk: IN std_logic;
rst: IN std_logic;
setPoint: IN std_logic_vector(3 DOWNTO 0);
PWM_out:OUT std_logic);
end PWM_Mod16;
ARCHITECTURE behavioral OF PWM_Mod16 IS
SIGNAL ctr_pre: integer := 0;
SIGNAL ctr_pwm: integer := 0;
SIGNAL pwm_clk_en:std_logic;
CONSTANT Tick_ms: INTEGER := 1;
CONSTANT FrecClkMHz:INTEGER := 100;
CONSTANT TimeOutPrescaler: INTEGER := Tick_ms * 1000 * FrecClkMHz -1;
CONSTANT PWM_Steps: INTEGER := 15;
SIGNAL Threshold:integer := 0;
BEGIN
prescaler: PROCESS (clk)
BEGIN
IF(rising_edge(clk))THEN
IF(rst = '1') THEN
ctr_pre<=0;
ELSIF ctr_pre = TimeOutPrescaler THEN
ctr_pre <= 0;
ELSE
ctr_pre <= ctr_pre + 1;
END IF;
END IF;
END PROCESS;
pwm_clk_en <= '1' WHEN ctr_pre = TimeOutPrescaler ELSE '0';
ResgisterInputs_proc: PROCESS (clk)
BEGIN
IF(rising_edge(clk)) THEN
IF(pwm_clk_en = '1') THEN
IF ctr_pwm = PWM_Steps THEN
Threshold <= to_integer(unsigned(setPoint));
END IF;
END IF;
END IF;
END PROCESS;
-- EXERCISE: define the rest of the circuit
END behavioral;
.XDC
## This file is a general .xdc for the Nexys4 DDR Rev. C
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];
##Switches
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { setPoint[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { setPoint[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { setPoint[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { setPoint[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
## LEDs
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { PWM_out }]; #IO_L18P_T2_A24_15 Sch=led[0]
STATES MACHINES
MOORE
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY stMachineMoore IS
PORT (CLK: IN STD_LOGIC;
RST: IN STD_LOGIC;
IN0: IN STD_LOGIC;
OUTV: OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00");
END stMachineMoore;
ARCHITECTURE Behavioral OF stMachineMoore IS
TYPE states_t IS (stSTART,stLEFT,stRIGHT);
SIGNAL currState: states_t := stSTART; --selfinti
SIGNAL nextState: states_t := stSTART; --selfinti
BEGIN
SYNC_PROC: PROCESS (CLK) --just clock
BEGIN
IF(rising_edge(CLK)) THEN
IF(RST = '1') THEN
currState <= stSTART;
ELSE
-- IF ENABLE_STATE_MACHINE = '1' THEN
currState <= nextState;
-- END IF;
END IF;
END IF;
END PROCESS;
NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs
BEGIN
nextState <= currState;
CASE currState IS
WHEN stSTART =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
WHEN stRIGHT =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
WHEN stLEFT =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
END CASE;
END PROCESS;
--or other combinational structure
OUTPUT_DECODE: PROCESS (currState) --just current state
BEGIN
CASE currState IS
WHEN stSTART =>
OUTV <= "00";
WHEN stRIGHT =>
OUTV <= "01";
WHEN stLEFT =>
OUTV <= "10";
END CASE;
END PROCESS;
END Behavioral;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY stMachineMoore IS
PORT (CLK: IN STD_LOGIC;
RST: IN STD_LOGIC;
IN0: IN STD_LOGIC;
OUTV: OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00");
END stMachineMoore;
ARCHITECTURE Behavioral OF stMachineMoore IS
TYPE states_t IS (stSTART,stLEFT,stRIGHT);
SIGNAL currState: states_t := stSTART; --selfinti
SIGNAL nextState: states_t := stSTART; --selfinti
BEGIN
SYNC_PROC: PROCESS (CLK) --just clock
BEGIN
IF(rising_edge(CLK)) THEN
IF(RST = '1') THEN
currState <= stSTART;
ELSE
-- IF ENABLE_STATE_MACHINE = '1' THEN
currState <= nextState;
-- END IF;
END IF;
END IF;
END PROCESS;
NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs
BEGIN
nextState <= currState;
CASE currState IS
WHEN stSTART =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
WHEN stRIGHT =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
WHEN stLEFT =>
IF(IN0 = '1') THEN
nextState <= stRIGHT;
ELSE
nextState <= stLEFT;
END IF;
END CASE;
END PROCESS;
OUTPUT_DECODE: PROCESS (currState) --just current state
BEGIN
CASE currState IS
WHEN stSTART =>
OUTV <= "00";
WHEN stRIGHT =>
OUTV <= "01";
WHEN stLEFT =>
OUTV <= "10";
END CASE;
END PROCESS;
END Behavioral;
STATE MACHINES
MEALY
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY stMachineMealy IS
PORT (CLK: IN STD_LOGIC;
RST: IN STD_LOGIC;
IN0: IN STD_LOGIC;
OUTV: OUT STD_LOGIC);
END stMachineMealy;
ARCHITECTURE Behavioral OF stMachineMealy IS
TYPE states_t IS (stSTART,st1,st0);
SIGNAL currState: states_t := stSTART; --selfinit
SIGNAL nextState: states_t := stSTART; --selfinit
SIGNAL OUTV_in: STD_LOGIC := '0';
BEGIN
SYNC_PROC: PROCESS (CLK) -- just clock
BEGIN
IF(rising_edge(CLK)) THEN
IF(RST = '1') THEN
currState <= stSTART;
OUTV<= '0';
ELSE
-- IF ENABLE_STATE_MACHINE = '1' THEN
currState <= nextState;
OUTV <= OUTV_in;
-- END IF;
END IF;
END IF;
END PROCESS;
NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs
BEGIN
nextState <= currState;
CASE currState IS
WHEN stSTART =>
IF(IN0 = '1') THEN
nextState <= st0;
ELSE
nextState <= st1;
END IF;
WHEN st0 =>
IF(IN0 = '1') THEN
nextState <= st1;
ELSE
nextState <= st0;
END IF;
WHEN st1 =>
IF(IN0 = '1') THEN
nextState <= st0;
ELSE
nextState <= st1;
END IF;
END CASE;
END PROCESS;
OUTPUT_DECODE: PROCESS (currState, IN0) --Current state + all inputs
BEGIN
CASE currState IS
WHEN stSTART =>
IF IN0 = '1' THEN
OUTV_in <= '0';
ELSE
OUTV_in <= '1';
END IF;
WHEN st0 =>
IF IN0 = '1' THEN
OUTV_in <= '0';
ELSE
OUTV_in <= '0';
END IF;
WHEN st1 =>
IF IN0 = '1' THEN
OUTV_in <= '1';
ELSE
OUTV_in <= '0';
END IF;
END CASE;
END PROCESS;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY stMachineMealy IS
PORT (CLK: IN STD_LOGIC;
RST: IN STD_LOGIC;
IN0: IN STD_LOGIC;
OUTV: OUT STD_LOGIC);
END stMachineMealy;
ARCHITECTURE Behavioral OF stMachineMealy IS
TYPE states_t IS (stSTART,st1,st0);
SIGNAL currState: states_t := stSTART; --selfinti
SIGNAL nextState: states_t := stSTART; --selfinti
SIGNAL OUTV_in: STD_LOGIC := '0';
BEGIN
SYNC_PROC: PROCESS (CLK) -- just clock
BEGIN
IF(rising_edge(CLK)) THEN
IF(RST = '1') THEN
currState <= stSTART;
OUTV<= '0';
ELSE
-- IF ENABLE_STATE_MACHINE = '1' THEN
currState <= nextState;
OUTV <= OUTV_in;
-- END IF;
END IF;
END IF;
END PROCESS;
NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs
BEGIN
nextState <= currState;
CASE currState IS
WHEN stSTART =>
IF(IN0 = '1') THEN
nextState <= st0;
ELSE
nextState <= st1;
END IF;
WHEN st0 =>
IF(IN0 = '1') THEN
nextState <= st1;
ELSE
nextState <= st0;
END IF;
WHEN st1 =>
IF(IN0 = '1') THEN
nextState <= st0;
ELSE
nextState <= st1;
END IF;
END CASE;
END PROCESS;
OUTPUT_DECODE: PROCESS (currState, IN0) --Current state + all inputs
BEGIN
CASE currState IS
WHEN stSTART =>
IF IN0 = '1' THEN
OUTV_in <= '0';
ELSE
OUTV_in <= '1';
END IF;
WHEN st0 =>
IF IN0 = '1' THEN
OUTV_in <= '0';
ELSE
OUTV_in <= '0';
END IF;
WHEN st1 =>
IF IN0 = '1' THEN
OUTV_in <= '1';
ELSE
OUTV_in <= '0';
END IF;
END CASE;
END PROCESS;
Stepper
Unipolar Bipolar
Stepper
Dev. 1a → 1 0 0 0
Dev. 1b → 0 0 1 0
Dev. 2a → 0 1 0 0
Dev. 2b → 0 0 0 1
Dev. 1a → 1 1 0 0
Dev. 1b → 0 0 1 1
Dev. 2a → 0 1 1 0
Dev. 2b → 1 0 0 1
2 phases
Higher torque
1 phase
Full step
Stepper
Dev. 1ª → 1 1 0 0 0 0 0 1
Dev. 1b → 0 0 0 1 1 1 0 0
Dev. 2ª → 0 1 1 1 0 0 0 0
Dev. 2b → 0 0 0 0 0 1 1 1
Half step
Stepper
Full step
2 phases
Inputs:
*Start-Stop
*Dir
Output
Ttor gate level
Libraries and packages
• Default std, work
Utils
Utils
Debounce
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Debouce is
Generic(
constant stages:integer := 8);
Port ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
end Debouce;
architecture Behavioral of Debouce is
type State_Type is (LoadNewBit, WaitTimeOut);
signal State : State_Type := LoadNewBit;
signal DPB, SPB : STD_LOGIC;
signal DReg : STD_LOGIC_VECTOR (stages - 1 downto 0);
signal ones_Vector : STD_LOGIC_VECTOR (stages - 1 downto 0) := (others => '1');
signal zeroes_Vector : STD_LOGIC_VECTOR (stages - 1 downto 0) := (others => '0');
constant foscMHz : integer := 100;
-- twindow
constant debounceTimeOutms : integer := 16;
-- tsample
constant DelayTicks : integer := (debounceTimeOutms / stages * 1000 * foscMHz);
begin
begin
process (clk_i) --SHIFT REGISTER
variable SDC : integer;
begin
if (rising_edge(clk_i)) then
if(rst_i = '1') then
Dreg <= zeroes_Vector;
else
DPB <= SPB; -- Double latch input signal
SPB <= D_i;
case State is
when LoadNewBit =>
DReg <= DReg(stages - 2 downto 0) & DPB;
SDC := DelayTicks;
State <= WaitTimeOut;
when WaitTimeOut =>
SDC := SDC - 1; --Software alike!!!
if SDC = 0 then
State <= LoadNewBit;
end if;
when others =>
State <= LoadNewBit;
end case;
end if;
end if;
end process;
process(clk_i) --COMPARATOR & RS flip flop
begin
if(rising_edge(clk_i)) then
if(rst_i = '1') then
D_o <= '0';
else
if DReg = ones_Vector then
D_o <= '1';
elsif DReg = zeroes_Vector then
D_o <= '0';
end if;
end if;
end if;
end process;
end Behavioral;
One-shot
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity one_shot is
Port ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
end one_shot;
architecture Behavioral of one_shot is
signal Q1 : std_logic;
begin
process(clk_i)
begin
if (rising_edge(clk_i)) then
if (rst_i = '1') then
Q1 <= '0';
else
Q1 <= D_i;
end if;
end if;
end process;
D_o <= D_i and (not Q1);
end Behavioral;
Button
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY button IS
PORT ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
END button;
architecture Behavioral of button is
COMPONENT one_shot is
PORT ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
END COMPONENT;
COMPONENT Debouce is
Port ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
end COMPONENT;
SIGNAL d_ii: STD_LOGIC := '0';
BEGIN
d: Debouce PORT MAP(
D_i =>D_i,
clk_i => clk_i,
rst_i => rst_i,
D_o => d_ii);
o: one_shot PORT MAP(
D_i => d_ii,
clk_i => clk_i,
rst_i => rst_i,
D_o => D_o);
END Behavioral;
Timed crosswalk regulted traffic light
• The traffic light should be green for at least 32 s. If a
pedestrian asserts the switch before that time elapses,
the traffic light will remain green for those 32 s. If that
time was over, the pedestraian would not wait. Then,
orange light will be on for 5 s. After that, pedestrians
will be able to cross safely for 12 s.
clk
rst
PASO PEATONES
TEMPORIZADO
VerdeC
NaranjaC
RojoC
VerdeP
RojoP
Pulsador
Outputs:[VerdeC,NaranjaC,RojoC,VerdeP,VerdeC]
stEsperaPulsador
stEsperaTimeOut
Coches
stNaranjaCoches
stEsperaTimeOut
Peaones
to_coches to_naranja
to_peatones
1,0,0,0,1 1,0,0,0,1 0,1,0,0,1 0,0,1,1,0
one_shot
debounce
TIMER_COCHES
TIMER_NARANJA
TIMER_PEATONES
STATE
MACHINE
to_naranja
to_peatones
to_coches
pulsador_i
Pulsador
clk
rst rst
rst
rst
rst
rst
VerdeC
NaranjaC
RojoC
VerdeP
RojoP
Button
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
entity PasoSemaforo is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
Pulsador : in STD_LOGIC;
VerdeC : out STD_LOGIC;
NaranjaC : out STD_LOGIC;
RojoC : out STD_LOGIC;
VerdeP : out STD_LOGIC;
RojoP : out STD_LOGIC);
end PasoSemaforo;
architecture Behavioral of PasoSemaforo is
--
component button IS
PORT ( D_i : in STD_LOGIC;
clk_i : in STD_LOGIC;
rst_i : in STD_LOGIC;
D_o : out STD_LOGIC);
END component;
type PasoSemaforo_t is
(stEsperaPulsador,stEsperaTimeOutCoches,stNaranjaCoches,stEs
peraTimeOutPeaones);
signal EstActual, EstSiguiente : PasoSemaforo_t :=
stEsperaPulsador;
signal timerCoches,timerNaranja,timerPeatones: INTEGER;
signal to_coches,to_naranja,to_peatones:STD_LOGIC;
signal pulsador_i:STD_LOGIC;
constant escala_tiempo:INTEGER:=100000; --ms
--constant escala_tiempo:INTEGER:=100000000; --segundos
constant timeout_Coches:INTEGER := 32*escala_tiempo-1;
constant timeout_Naranja:INTEGER := 5*escala_tiempo-1;
constant timeout_Peatones:INTEGER := 12*escala_tiempo-1;
begin
stEsperaPulsador
stEsperaTimeOut
Coches
stNaranjaCoches
stEsperaTimeOut
Peaones
to_coches to_naranja
to_peatones
1,0,0,0,1 1,0,0,0,1 0,1,0,0,1 0,0,1,1,0
one_shot
debounce
TIMER_COCHES
TIMER_NARANJA
TIMER_PEATONES
STATE
MACHINE
to_naranja
to_peatones
to_coches
pulsador_i
Pulsador
clk
rst rst
rst
rst
rst
rst
VerdeC
NaranjaC
RojoC
VerdeP
RojoP
Button
PUSLADOR_FILTRADO: button PORT MAP(
clk_i => clk,
rst_i => rst,
D_i => Pulsador,
D_o => Pulsador_i
);
TIMER_COCHES: process(clk)
begin
if(rising_edge(clk))then
if(rst = '1') then
timerCoches <= 0;
else
if (EstActual = stEsperaTimeOutPeaones) then
timerCoches <= 0;
else
if (timerCoches /= timeout_Coches) then
timerCoches <= timerCoches + 1;
else
timerCoches <= timerCoches;
end if;
end if;
end if;
end if;
end process;
to_coches <= '1' when timerCoches = timeout_Coches else '0';
TIMER_NARANJA: process(clk)
begin
if(rising_edge(clk))then
if(rst = '1') then
timerNaranja <= 0;
else
if (EstActual = stNaranjaCoches) then
if (timerNaranja = timeout_Naranja) then
timerNaranja <= 0;
else
timerNaranja <= timerNaranja + 1;
end if;
else
timerNaranja <= 0;
end if;
end if;
end if;
end process;
to_Naranja <= '1' when timerNaranja = timeout_Naranja else '0';
Component Instantation
Count only during certain states
TIMER_PEATONES: process(clk)
begin
if(rising_edge(clk))then
if(rst = '1') then
timerPeatones <= 0;
else
if (EstActual = stEsperaTimeOutPeaones) then
if (timerPeatones = timeout_Peatones) then
timerPeatones <= 0;
else
timerPeatones <= timerPeatones + 1;
end if;
else
timerPeatones <= 0;
end if;
end if;
end if;
end process;
to_peatones <= '1' when timerPeatones = timeout_Peatones else '0';
one_shot
debounce
TIMER_COCHES
TIMER_NARANJA
TIMER_PEATONES
STATE
MACHINE
to_naranja
to_peatones
to_coches
pulsador_i
Pulsador
clk
rst rst
rst
rst
rst
rst
VerdeC
NaranjaC
RojoC
VerdeP
RojoP
Button
SYNC_PROC: process (clk)
begin
if (rising_edge(clk)) then
if (rst = '1') then
EstActual <= stEsperaPulsador;
else
EstActual <= EstSiguiente;
end if;
end if;
end process;
NEXT_STATE_DECODE: process (EstActual,pulsador_i,to_coches,
to_naranja,to_peatones)
begin
EstSiguiente <= EstActual; --default is to stay in current state
--insert statements to decode next_state
--below is a simple example
case (EstActual) is
when stEsperaPulsador =>
if(pulsador_i = '1') then
EstSiguiente <= stEsperaTimeOutCoches;
end if;
when stEsperaTimeOutCoches =>
if(to_coches = '1') then
EstSiguiente <= stNaranjaCoches;
end if;
when stNaranjaCoches =>
if(to_naranja = '1') then
EstSiguiente <= stEsperaTimeOutPeaones;
end if;
when stEsperaTimeOutPeaones =>
if(to_peatones = '1') then
EstSiguiente <= stEsperaPulsador;
end if;
when others=>
EstSiguiente <= stEsperaPulsador;
end case;
end process;
OUTPUT_DECODE: process (EstActual)
begin
case (EstActual) is
when stEsperaPulsador =>
VerdeC <= '1'; NaranjaC <= '0';RojoC<='0';VerdeP<='0';RojoP<='1';
when stEsperaTimeOutCoches =>
VerdeC <= '1'; NaranjaC <= '0';RojoC<='0';VerdeP<='0';RojoP<='1';
when stNaranjaCoches =>
VerdeC <= '0'; NaranjaC <= '1';RojoC<='0';VerdeP<='0';RojoP<='1';
when stEsperaTimeOutPeaones =>
VerdeC <= '0'; NaranjaC <= '0';RojoC<='1';VerdeP<='1';RojoP<='0';
end case;
stEsperaPulsador
stEsperaTimeOut
Coches
stNaranjaCoches
stEsperaTimeOut
Peaones
to_coches to_naranja
to_peatones
1,0,0,0,1 1,0,0,0,1 0,1,0,0,1 0,0,1,1,0
Nexys 4 DDR
• https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start
Nexys 4 DDR
• Displays
More on FPGA synthesis
• One-process vs 2-process FSM
– https://vhdlwhiz.com/n-process-state-machine/
• http://www.rs-
online.com/designspark/electronics/nodes/view/type:
knowledge-item/slug:how-to-implement-state-
machines-in-your-fpga
• State machine encoding “Using FPGA in Mission-
Critical Systems” Xcell73 pp.16-19
• 10 FPGA Design Techniques you should know
– https://forums.xilinx.com/t5/Xcell-Daily-Blog-
Archived/Adam-Taylor-thinks-there-are-ten-FPGA-design-
techniques-that-you/ba-p/709550
COLOURED COPY PASTE
• COPY in ISE
• PASTE IN NotePad++ (Language VHDL)
• PlugIns ->NppExport->Copy RTF
• Paste in WORD
• Copy in WORD
• PASTE in PPT (without selecting any text input)
entity bies_jk is
Port ( clk : in STD_LOGIC;
j : in STD_LOGIC;
k : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
q : out STD_LOGIC;
qn : out STD_LOGIC);
end bies_jk;
architecture Behavioral of bies_jk is
signal in_q: std_logic := '0';
begin
process (clk)
begin
if rising_edge(clk) then
if rst='1' then
in_q <= '0';
elsif ce ='1' then
if (j='0' and k='0') then
in_q <= in_q;
elsif (j='0' and k='1') then
in_q <= '0';
elsif (j='1' and k='0') then
in_q <= '1';
elsif (j='1' and k='1') then
in_q <= not (in_q);
end if;
end if;
end if;
end process;
q <= in_q;
qn <= NOT in_q;
VHDL
Libraries and Types
WHEN ELSE
WITH SELECT
PROCESS
IF-THEN-ELSIF-ELSE
CASE WHEN
FOR
Components
Testbenches and simulation
Updated: 17 October 2023.

m4_VHDL_ED.pdf

  • 1.
    VHDL Libraries and Types WHENELSE WITH SELECT PROCESS IF-THEN-ELSIF-ELSE CASE WHEN FOR Components Testbenches and simulation Updated: 17 October 2023.
  • 2.
    References • Diseño deCircuitos Digitales con VHDL Online – Machado Sanchez, Borromeo López – Dpto. Tecnología Electrónica Universidad Rey Juan Carlos • Electrónica digital : aplicaciones y problemas con VHDL. – Prentice Hall, Madrid [etc.] : 2002. • Diseño de Sistemas Digitales con VHDL – Pérez, Soto, Fernández – Ed. Paraninfo, 2002 • Vhdl for Programmable Logic – Kevin Skahill – Cypress semiconductor
  • 3.
    VHDL • VHSIC HardwareDescription Language – Very High Speed Integrated Circuit • Models and simulates from high level descriptions to gates or flip-flops • Concurrency support • Synthesis • Hierarchy design top-down or down-top Hardware Description!!!!!
  • 4.
    Pros • “Rapid” Prototyping •Strongly typed • Independent of technology and methodology • Normalized • Documentation, design and simulation • Reusability (IP cores)
  • 5.
    Cons • Committee drivenlanguage • Strongly typed • Not everything can be synthesised but can be modelled and simulated – Lack of portability across platforms • Think it is HARDWARE!
  • 6.
  • 7.
    Libraries • IEEE Libs –STD_LOGIC_1164 – STD_LOGIC_UNSIGNED – STD_LOGIC_SIGNED – STD_LOGIC_ARITH – NUMERIC_STD • STD – STANDARD – TEXTIO • WORK -
  • 8.
    TYPES • Integer -MAXINT...MAXINT •Natural 0...MAXINT • Positive 1...MAXINT • Real -MAXREAL...MAXREAL • Boolean TRUE, FALSE • Bit 0,1 • Bit_vector Bit array • Character 256 • String Char array • Time -MAXINT...MAXINT <unit> – MAXINT = 231-1 – MAXREAL=1.0E38
  • 9.
    USER TYPES • Userdefined • Subrange • Array • Record TYPE StateMach IS (IDLE,S0,S1,S2); TYPE fan IS RANGE 1 TO 20; TYPE MemRAM IS ARRAY (0 to 255) OF STD_LOGIC_VECTOR(7 DOWNTO 0); SUBTYPE Decade IS INTEGER RANGE 0 to 9; TYPE LogicGateTiming IS RECORD PropTime: TIME; SetUp: TIME; Hold: TIME END RECORD;
  • 10.
    STD_LOGIC_1164 • STD_LOGIC • STD_LOGIC_VECTOR U X O 1 Uninitialized Unknown.Impossible to determine this value/result. Logic ‘0’ Logic ‘1’ Z W L H - High impedance Weak signal Weak. Probably ‘0’ Weak. Probalby “1” Don’t care Defined: and, nand, or, nor, xor, xnor, not What about +,-,*…? SIGNAL SigVector : STD_LOGIC_VECTOR (7 downto 0); SIGNAL Sig : STD_LOGIC; More tan ‘0’ and ‘1’!!
  • 11.
    Operators • Arithmetic +,-,*,/,**,mod,rem,abs (checkfor type) • Relational =,/=,>,>=,<,<= • Logical and, nand, or, nor, xor, xnor, not • Shift sll, srl,sla,sra,rol,ror • Concatenate &
  • 12.
    OBJECTS • CONSTANT • SIGNAL(HW related) • VARIABLES (Process, Function and Procedure) • FILES CONSTANT V37: STD_LOGIC_VECTOR (7 downto 0) := "01011010"; SIGNAL Addbus: STD_LOGIC_VECTOR(15 downto 0):= x"0000"; Addbus <= x"000“ & “1001”; VARIABLE ctrT : INTEGER RANGE 0 TO 1000 := 800; ctrT := 123; USE std.textio.ALL; TYPE t_sFile IS FILE OF STRING; FILE InputFile: t_sFile OPEN READ_MODE IS "C:VHDLTUTOVectors.txt";
  • 13.
    ENTITY ENTITY <entity_name> IS GENERIC( <generic_name> : <type> := <value>; <other generics>... ); PORT ( <port_name> : <mode> <type>; <other ports>... ); END <entity_name>; “Port” always!!!
  • 14.
    MODE: IN OUT INOUT BUFFER LINKAGE ENTITY PARITY IS GENERIC( N : INTEGER := 8; Delay : TIME := 10 ns); PORT ( A : IN STD_LOGIC_VECTOR (N-1 downto 0) := (OTHERS =>'0'); ODD : OUT STD_LOGIC); END PARITY;
  • 15.
    ARCHITECTURE ARCHITECTURE <arch_name> OF<entity_name> IS -- declarative_items ( -- signal declarations, -- component declarations, -- etc.) BEGIN -- architecture body END <arch_name>; Component description!!!
  • 16.
    DESCRIPTIONS • Behavioural: Highlevel or algorithmic • Dataflow: RTL (register transfer level) • Structural: Logic components • Mixed
  • 17.
  • 18.
    WHEN...ELSE <name> <= <expression>when <condition> else <expression> when <condition> else <expression>; s <= "00" WHEN a = b ELSE "01" WHEN a > b ELSE "11"; s1 <= d1 WHEN control = '1' ELSE UNAFFECTED; s2 <= d2 WHEN control = '1' ELSE s2; s <= "00" WHEN (A='0' AND B='0' AND ENABLE ='1') ELSE "01" WHEN (A='1' AND B='0' AND ENABLE ='1') ELSE "01" WHEN (A='0' AND B='1' AND ENABLE ='1') ELSE “10" WHEN (A='1' AND B='1' AND ENABLE ='1') ELSE UNAFFECTED; Conditional.
  • 19.
    WITH...SELECT WITH <choice_expression> SELECT <name><= <expression> WHEN <choices>, <expression> WHEN <choices>, <expression> WHEN OTHERS; WITH w SELECT F<= "0000001" WHEN "0000", --0 "1001111" WHEN "0001", --1 "0010010" WHEN "0010“, --2 "0000110" WHEN "0011", "1001100" WHEN "0100", "0100100" WHEN "0101", "0100000" WHEN "0110", "0001111" WHEN "0111", "0000000" WHEN "1000", "0000100" WHEN "1001", "0000010" WHEN "1010", "1100000" WHEN "1011", "0110001" WHEN "1100", "1000010" WHEN "1101", "0010000" WHEN "1110", "0111000" WHEN "1111"; Conditional.
  • 20.
    WITH (ENABLE &A & B) SELECT s <= "00" WHEN "000", "01" WHEN "110" | "101", "11" WHEN "111", UNAFFECTED WHEN OTHERS;
  • 21.
    PROCESS - WAIT <label>:PROCESS(<all_input_signals_separated_by_commas>) -- declarative_items -- variable and constant declarations, -- types or subtypes declarations BEGIN <statements>; END PROCESS; G: PROCESS BEGIN G0 <= '1' AFTER 5 ns, '0' AFTER 10 ns, '1' AFTER 15 ns, '0' AFTER 20 ns; G1 <= '1' AFTER 5 ns, '0' AFTER 15 ns; WAIT; END PROCESS G; G: PROCESS BEGIN WAIT FOR 5ns; --5ns G0 <= '1'; G1 <= '1'; WAIT FOR 5ns; --10ns G0 <= '0'; WAIT FOR 5ns; --15ns G0 <= '1'; G1 <= '0'; WAIT FOR 5ns; --20ns G0 <= '0'; WAIT; END PROCESS G; Sensitivity list!!! All the variables that, when changed, need the process to be activated.
  • 22.
    BIN_COMP : PROCESS BEGIN WAITON A, B, ENABLE; . . . END PROCESS; BIN_COMP : PROCESS (A,B,ENABLE) BEGIN . . . END PROCESS; ENTITY example PORT ( c: IN std_logic; d: OUT std_logic); END ENTITY; ARCHITECTURE ex_arch OF example IS SIGNAL a,b: std_logic; BEGIN PROCESS(c) VARIABLE z: std_logic; BEGIN a<= c and b;--SIGNAL assignation: 'a' same value until reach end of the PROCESS z:= a or c; --VARIABLES assignation: after evaluate this line z = a or c with -- a = the value at the beginning of the PROCESS END PROCESS; END ARCHITECTURE;
  • 23.
    PROCESS -- A,B,C,X Variables --A=0, B=1, C=2, X=3 BEGIN WAIT UNTIL CLK ='1'; A := B + C; --1+2 X := A + C; --3+2 A := X + C; --5+2 END PROCESS; -- A = 7, X = 5 PROCESS -- A,B,C,X SIGNALS -- A=0, B=1, C=2, X=3 BEGIN WAIT UNTIL CLK ='1'; A <= B + C; --1+2 X <= A + C; --0+2 A <= X + C; --3+2 END PROCESS; -- A = 5, X = 2 Assignation. All the variables change at the same time!!! XX <= IN; OUT <= XX; SIGNAL1 <= SIGNAL2.
  • 24.
    IF-THEN-ELSIF-ELSE IF <condition> THEN <statement>; ELSIF<condition> THEN <statement>; ELSE <statement>; END IF; Conditional. Inside Process.
  • 25.
    ARCHITECTURE dataflow OFFirst IS SIGNAL inS : STD_LOGIC_VECTOR (1 DOWNTO 0); BEGIN prc: PROCESS (A,B,ENABLE) VARIABLE AG: STD_LOGIC_VECTOR (2 downto 0); BEGIN AG := A & B & ENABLE; IF AG = "000" THEN inS <= "00"; ELSIF (AG = "110" OR AG = "101") THEN inS <= "01" ; ELSIF AG = "111" THEN inS <= "11"; ELSE inS <= inS; END IF; END PROCESS; S <= inS; END dataflow;
  • 26.
    CASE-WHEN CASE (<2-bit select>)IS WHEN "00" => <statement>; WHEN "01" => <statement>; WHEN "10" => <statement>; WHEN "11" => <statement>; WHEN OTHERS => <statement>; END CASE; Conditional. Inside Process.
  • 27.
    CASE a IS WHEN0 => B:=0; WHEN 1 to 50 => B:=1; WHEN 99 to 51 => B:=2; WHEN OTHERS => B:=3; END CASE; CASE w IS WHEN "0000" => F<= "0000001"; --0 WHEN "0001" => F<= "1001111"; --1 WHEN "0010" => F<= "0010010"; --2 WHEN "0011" => F<= "0000110"; WHEN "0100" => F<= "1001100"; WHEN "0101" => F<= "0100100"; WHEN "0110" => F<= "0100000"; WHEN "0111" => F<= "0001111"; WHEN "1000" => F<= "0000000"; WHEN "1001" => F<= "0000100"; WHEN "1010" => F<= "0000010"; WHEN "1011" => F<= "1100000"; WHEN "1100" => F<= "0110001"; WHEN "1101" => F<= "1000010"; WHEN "1110" => F<= "0010000"; WHEN "1111" => F<= "0111000";
  • 28.
    ARCHITECTURE dataflow OFFirst IS SIGNAL inS : STD_LOGIC_VECTOR (1 downto 0); BEGIN prc: PROCESS (A,B,ENABLE) VARIABLE AG: STD_LOGIC_VECTOR (2 downto 0); BEGIN AG := A & B & ENABLE; CASE AG IS WHEN "000" => inS <= "00"; WHEN "110" | "101" => inS <= "01"; WHEN "111" => inS <= "11"; WHEN OTHERS => NULL; END CASE; END PROCESS; S <= inS; END dataflow;
  • 29.
    FOR LOOP FOR <name>IN <lower_limit> TO <upper_limit> LOOP <statement>; <statement>; END LOOP; PROCESS (A) VARIABLE TMP : STD_LOGIC; BEGIN TMP := '0'; FOR I IN A'LOW TO A'HIGH LOOP TMP := TMP XOR A(I); END LOOP; ODD <= TMP; END PROCESS;
  • 30.
    • Support forsynthesis – the loop range is static (i.e. implies a definite number of iterations), unroll it and – the loop contains no wait statements. PROCESS (y) VARIABLE power_N : INTEGER; BEGIN power_N := y; FOR I IN N DOWNTO 2 LOOP power_N := power_N * y; END LOOP; END PROCESS;
  • 31.
    WHILE LOOP WHILE <condition>LOOP <statement>; <statement>; END LOOP; PROCESS --Testbench clock generator BEGIN WHILE TRUE LOOP CLK <= not CLK ; WAIT FOR PERIOD/2; END LOOP; WAIT; END PROCESS;
  • 32.
    PROCESS (y) VARIABLE I: INTEGER RANGE 0 TO 8 := 0; VARIABLE power_N : INTEGER; BEGIN I := 0; power_N := y; WHILE I < N LOOP power_N := power_N * y; I := I + 1; END LOOP; END PROCESS;
  • 33.
    EXIT NEXT <label:> NEXT<loop_label:> <WHEN boolean_expr>; <label:> EXIT <loop_label:> <WHEN boolean_expr>; Loop_1: FOR count_value IN 1 TO 10 LOOP EXIT Loop_1 WHEN reset = '1'; A_1: A(count_value) := '0'; END LOOP Loop_1; A_2: B <= A AFTER 10 ns; Loop_Z: FOR count_value IN 1 TO 8 LOOP Assign_1: A(count_value) := '0'; NEXT WHEN condition_1; Assign_2: A(count_value + 8) := '0'; END LOOP Loop_Z;
  • 34.
    COMPONENTS ARCHITECTURE MyArch OFMyEnt IS --SIGNAL DECL COMPONENT <component_name> GENERIC ( <generic_name> : <type> := <value>; <other generics>... ); PORT ( <port_name> : <mode> <type>; <other ports>... ); END COMPONENT; BEGIN <instance_name> : <component_name> GENERIC MAP ( <generic_name> => <value>, <other generics>... ) PORT MAP ( <port_name> => <signal_name>, <other ports>... );
  • 35.
  • 36.
  • 37.
    ARCHITECTURE behavior OFtb_adderN IS CONSTANT NAd: INTEGER := 4; COMPONENT adder_N GENERIC( N : INTEGER); PORT( a : IN std_logic_vector(NAd -1 downto 0); b : IN std_logic_vector(NAd -1 downto 0); cin : IN std_logic; cout : OUT std_logic; s : OUT std_logic_vector(NAd -1 downto 0) ); END COMPONENT; SIGNAL a : std_logic_vector(NAd -1 downto 0) := (others => '0'); SIGNAL b : std_logic_vector(NAd -1 downto 0) := (others => '0'); SIGNAL cin : std_logic := '0'; SIGNAL cout : std_logic; SIGNAL s : std_logic_vector(NAd -1 downto 0); BEGIN uut: adder_N GENERIC MAP (N => NAd) PORT MAP ( a => a, b => b, cin => cin, cout => cout, s => s);
  • 38.
    -- Stimulus process stim_proc:PROCESS BEGIN WAIT FOR 1 us; a <= "1111"; b <= "0001"; WAIT FOR 10 us; a <= "0101"; b <= "0011"; WAIT FOR 10 us; a <= "1001"; b <= "0101"; WAIT ; END PROCESS; END;
  • 39.
    ARCHI________ CONSTANT clk_period :TIME := 10 ns; BEGIN -- Clock process definitions clk_process :PROCESS BEGIN clk <= '0'; WAIT FOR clk_period/2; clk <= '1'; WAIT FOR clk_period/2; END PROCESS;
  • 41.
    Combinational Circuits • Datatransmission – Multiplexor (Mux) – Demultiplexor (Demux) • Code Converters – Encoder – Decoder • Aritmetic & Logic – Comparator – Parity Generator/Checker – Adder COMBINATIONAL CIRCUITS I0 I1 Im O0 O1 On
  • 42.
    MUX LIBRARY ieee; USE ieee.std_logic_1164.ALL; USEieee.std_logic_unsigned.ALL; ENTITY mux4_1 IS PORT (s0 : IN STD_LOGIC; s1 : IN STD_LOGIC; in0 : IN STD_LOGIC; in1 : IN STD_LOGIC; in2 : IN STD_LOGIC; in3 : IN STD_LOGIC; output : OUT STD_LOGIC ); END mux4_1; http://www.quicknet.se/hdc/hdl/educaton/mux4_1/
  • 43.
    ARCHITECTURE if_example OFmux4_1 IS BEGIN mux:PROCESS(s0, s1, in0, in1, in2, in3) BEGIN IF (s0='0' AND s1='0') THEN output <= in0; ELSIF (s0='1' AND s1='0') THEN output <= in1; ELSIF (s0='0' AND s1='1') THEN output <= in2; ELSIF (s0='1' AND s1='1') THEN output <= in3; ELSE -- (s0 or s1 are not 0 or 1) output <= 'X'; END IF; END PROCESS mux; END if_example;
  • 44.
    ARCHITECTURE case_example OFmux4_1 IS BEGIN mux:PROCESS(s0, s1, in0, in1, in2, in3) VARIABLE sel : STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN sel := s1 & s0; -- concatenate s1 and s0 CASE sel IS WHEN "00" => output <= in0; WHEN "01" => output <= in1; WHEN "10" => output <= in2; WHEN "11" => output <= in3; WHEN OTHERS => output <= 'X'; END CASE; END PROCESS mux; END case_example;
  • 45.
    ARCHITECTURE with_example OFmux4_1 IS SIGNAL sel : STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN sel <= s1 & s0; -- concatenate s1 and s0 WITH sel SELECT output <= in0 WHEN "00", in1 WHEN "01", in2 WHEN "10", in3 WHEN "11", 'X' WHEN OTHERS; END with_example; ARCHITECTURE when_example OF mux4_1 IS BEGIN output <= in0 WHEN (s1 & s0)="00" ELSE in1 WHEN (s1 & s0)="01" ELSE in2 WHEN (s1 & s0)="10" ELSE in3 WHEN (s1 & s0)="11" ELSE 'X'; END when_example;
  • 46.
    Demultiplexer entity demux1a4 is Port( ENTRADA : in STD_LOGIC; SEL : in STD_LOGIC_VECTOR (1 downto 0); SALIDA : out STD_LOGIC_VECTOR (3 downto 0)); end demux1a4; architecture Behavioral of demux1a4 is begin SALIDA <= "000" & ENTRADA WHEN SEL = "00" ELSE "00" & ENTRADA & '0' WHEN SEL = "01" ELSE '0' & ENTRADA & "00" WHEN SEL = "10" ELSE ENTRADA & "000" WHEN SEL = "11" ELSE "0000"; end Behavioral; DEMUX I S1 O0 O1 O3 O2 S0
  • 47.
    Encoder/Decoder WITH w SELECT F<="0000001" WHEN "0000", --0 "1001111" WHEN "0001", --1 "0010010" WHEN "0010“, --2 "0000110" WHEN "0011", "1001100" WHEN "0100", "0100100" WHEN "0101", "0100000" WHEN "0110", "0001111" WHEN "0111", "0000000" WHEN "1000", "0000100" WHEN "1001", "0000010" WHEN "1010", --A "1100000" WHEN "1011", "0110001" WHEN "1100", "1000010" WHEN "1101", "0010000" WHEN "1110", "0111000" WHEN "1111"; --F ENCODER I0 I1 I2 n O0 O1 On DECODER I0 I1 In O0 O1 O2 n binary to 7 Segment decoder
  • 48.
    Comparator entity comp_n is generic(n: integer := 8); Port ( A : in STD_LOGIC_VECTOR (n downto 0); B : in STD_LOGIC_VECTOR (n downto 0); EQ : out STD_LOGIC; GT : out STD_LOGIC; LT : out STD_LOGIC); end comp_n; architecture Behavioral of comp_n is begin PROCESS (A,B) BEGIN IF (A=B) THEN EQ <= '1'; ELSE EQ <= '0'; END IF; END PROCESS; PROCESS (A,B) BEGIN IF (A>B) THEN GT <= '1'; ELSE GT <= '0'; END IF; END PROCESS; PROCESS (A,B) BEGIN IF (A<B) THEN LT <= '1'; ELSE LT <= '0'; END IF; END PROCESS; end Behavioral; COMPARATOR A GT EQ LT B
  • 49.
    Half Adder LIBRARY IEEE; USEIEEE.STD_LOGIC_1164.ALL; ENTITY HalfAdder IS Port ( a : IN STD_LOGIC; b : IN STD_LOGIC; s : OUT STD_LOGIC; co : OUT STD_LOGIC); END HalfAdder; I1 I1 I2 I2 O O
  • 50.
    ENTITY AND_2 IS GENERIC(PropDelay : TIME := 3 ns); PORT( I1 : IN STD_LOGIC; I2 : IN STD_LOGIC; O : OUT STD_LOGIC); END AND_2; ARCHITECTURE Behavioral OF AND_2 IS BEGIN O <= I1 AND I2 AFTER PropDelay; END Behavioral; ENTITY XOR_2 IS GENERIC( PropDelay : TIME := 3 ns); PORT( I1 : IN STD_LOGIC; I2 : IN STD_LOGIC; O : OUT STD_LOGIC); END XOR_2; ARCHITECTURE Behavioral OF XOR_2 IS BEGIN O <= I1 XOR I2 AFTER PropDelay; END Behavioral;
  • 51.
    ARCHITECTURE Behavioral OFHalfAdder IS COMPONENT XOR_2 IS GENERIC( PropDelay : TIME := 3 ns); PORT( I1 : IN STD_LOGIC; I2 : IN STD_LOGIC; O : OUT STD_LOGIC); END COMPONENT; COMPONENT AND_2 IS GENERIC( PropDelay : TIME := 3 ns); PORT( I1 : IN STD_LOGIC; I2 : IN STD_LOGIC; O : OUT STD_LOGIC); END COMPONENT; BEGIN AND_GATE: AND_2 GENERIC MAP(PropDelay => 5 ns) PORT MAP ( I1 => a, I2 => b, O => co); XOR_GATE: XOR_2 GENERIC MAP(PropDelay => 5 ns) PORT MAP ( I1 => a, I2 => b, O => s); END Behavioral;
  • 52.
  • 53.
    ARCHITECTURE Behavioral ofFullAdder is COMPONENT HalfAdder IS PORT ( a : IN STD_LOGIC; b : IN STD_LOGIC; s : OUT STD_LOGIC; co : OUT STD_LOGIC); END COMPONENT; SIGNAL P1,P2,P3 : STD_LOGIC; BEGIN HA1: HalfAdder PORT MAP( a => a, b => b, co => P2, s => P1 ); HA2: HalfAdder PORT MAP( a => P1, b => cin, co => P3, s => s ); co <= P2 OR P3; END Behavioral;
  • 54.
    GENERATE <label:> FOR parameterIN range GENERATE <concurrent statements> END GENERATE <label>; <label:> IF <boolean_expr> GENERATE <concurrent statements> END GENERATE <label>;
  • 55.
    ENTITY adder_N IS GENERIC( N: INTEGER := 8); PORT ( a : IN STD_LOGIC_VECTOR (N-1 downto 0); b : IN STD_LOGIC_VECTOR (N-1 downto 0); cin : IN STD_LOGIC; cout : OUT STD_LOGIC; s : OUT STD_LOGIC_VECTOR (N-1 downto 0)); END adder_N;
  • 56.
    ARCHITECTURE Behavioral OFadder_N IS COMPONENT FullAdder IS PORT ( a : In STD_LOGIC; b : IN STD_LOGIC; cin : IN STD_LOGIC; s : OUT STD_LOGIC; co : OUT STD_LOGIC); END COMPONENT; SIGNAL CARRIES: STD_LOGIC_VECTOR(N downto 1); BEGIN U0: FullAdder PORT MAP( a => a(0), b => b(0), cin => '0', co => CARRIES(1), s => s(0)); GenAdder_N: FOR I IN 1 TO N-1 GENERATE Ux: FullAdder PORT MAP( a => a(I), b => b(I), cin => CARRIES(I), co => CARRIES(I+1), s => S(I)); END GENERATE; cout <= CARRIES(N); END Behavioral;
  • 57.
    ARCHITECTURE Behavioral OFadder_N IS COMPONENT FullAdder IS PORT ( a : In STD_LOGIC; b : IN STD_LOGIC; cin : IN STD_LOGIC; s : OUT STD_LOGIC; co : OUT STD_LOGIC); END COMPONENT; SIGNAL CARRIES: STD_LOGIC_VECTOR(N downto 1); BEGIN GEN_ADD: FOR I IN 0 TO N-1 GENERATE LOWER_BIT: IF I=0 GENERATE U0: FullAdder PORT MAP (a => A(I), b => B(I), cin => '0', s => S(I), co => CARRIES(I+1)); END GENERATE LOWER_BIT; UPPER_BITS: IF I>0 GENERATE UX: FullAdder PORT MAP (a => A(I), b => B(I), cin => CARRIES(I), s => S(I), co => CARRIES(I+1)); END GENERATE UPPER_BITS; END GENERATE GEN_ADD; cout <= CARRIES(N); END Behavioral;
  • 58.
    Sequential circuits • Registers(RS, JK, D, T) • Counters • Shift Registers • States Machines COMBINATIONAL CIRCUITS INPUTS OUTPUTS COMBINATIONAL CIRCUITS MEMORY CLK
  • 59.
    Registers LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITYffSimple IS PORT ( clk : IN STD_LOGIC; D : IN STD_LOGIC; Q : OUT STD_LOGIC); END ffSimple; ARCHITECTURE Behavioral OF ffSimple IS BEGIN ff: PROCESS(clk) BEGIN IF(clk'event AND clk = '1') THEN -- IF (rising_edge(clk)) THEN Q <= D; END IF; END PROCESS; END Behavioral;
  • 61.
    Registers • Asynchronous RESET LIBRARYIEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY ffAsyncRST IS PORT ( clk : IN STD_LOGIC; RST: IN STD_LOGIC; D : IN STD_LOGIC; Q : OUT STD_LOGIC); END ffAsyncRST; ARCHITECTURE Behavioral OF ffAsyncRST IS BEGIN ff: PROCESS(clk,RST) BEGIN IF RST = '1' THEN – Asynchronous RST Q<= '0'; ELSIF(clk'event AND clk = '1') THEN Q <= D; END IF; END PROCESS; END Behavioral;
  • 63.
    Registers • Synchronous RESET LIBRARYIEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY ffSyncRST IS PORT ( clk : IN STD_LOGIC; RST: IN STD_LOGIC; D : IN STD_LOGIC; Q : OUT STD_LOGIC); END ffSyncRST; ARCHITECTURE Behavioral OF ffSyncRST IS BEGIN ff: PROCESS(clk) – No RST BEGIN IF (clk'event AND clk = '1') THEN IF RST = '1' THEN -- Synchronous RST Q<= '0'; ELSE Q <= D; END IF; END IF; END PROCESS; END Behavioral;
  • 65.
    Registers ENTITY ffSelfInit IS PORT( clk : IN STD_LOGIC; RST: IN STD_LOGIC; D : IN STD_LOGIC; Q : OUT STD_LOGIC := '0'); END ffSelfInit;
  • 66.
    Registers • Self Initwhen possible • RESET better active high and synchronous • RESET – SET – ENABLE • Rising_edge
  • 67.
    JK with CE entitybies_jk is Port ( clk : in STD_LOGIC; j : in STD_LOGIC; k : in STD_LOGIC; rst : in STD_LOGIC; ce : in STD_LOGIC; q : out STD_LOGIC; qn : out STD_LOGIC); end bies_jk; architecture Behavioral of bies_jk is signal in_q: std_logic := '0'; begin process (clk) begin if rising_edge(clk) then if rst='1' then in_q <= '0'; elsif ce ='1' then if (j='0' and k='0') then in_q <= in_q; elsif (j='0' and k='1') then in_q <= '0'; elsif (j='1' and k='0') then in_q <= '1'; elsif (j='1' and k='1') then in_q <= not (in_q); end if; end if; end if; end process; q <= in_q; qn <= NOT in_q; end Behavioral; J K Q Q RST ce
  • 68.
    Counter • More generic? LIBRARYieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_unsigned.ALL; -- Vector Arithmetic ENTITY counter IS PORT(CLK, CLR : IN STD_LOGIC; Q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END counter; ARCHITECTURE archi OF counter IS SIGNAL tmp: STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS (CLK) BEGIN IF (CLK'event AND CLK='1') THEN IF (CLR='1') THEN -- CLR Synchronous tmp <= "0000"; ELSE tmp <= tmp + 1; -- needs std_logic_unsigned END IF; END IF; END PROCESS; Q <= tmp; END archi;
  • 70.
    PWM LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USEieee.numeric_std.all; --STD_LOGIC_VECTOR to integer conversion ENTITY PWM_N IS PORT( clk : IN STD_LOGIC; rst : IN STD_LOGIC; period : IN STD_LOGIC_VECTOR(7 DOWNTO 0) := "00001111"; Ton : IN STD_LOGIC_VECTOR(7 DOWNTO 0) := "00001000" ; PWM_Out : OUT STD_LOGIC); END PWM_N; ARCHITECTURE Behavioral OF PWM_N IS SIGNAL ctr_tmp : INTEGER := 0; BEGIN timer: PROCESS(clk) BEGIN IF(rising_edge(clk))THEN IF(rst = '1') THEN ctr_tmp <= 0; ELSIF ctr_tmp = to_integer(unsigned(period)) then ctr_tmp <= 0; ELSE ctr_tmp <= ctr_tmp + 1; END IF; END IF; END PROCESS; PWM_Out <= '1' WHEN ctr_tmp <= to_integer(unsigned(Ton)) ELSE '0'; --PWM_Out <= '1' WHEN ctr_tmp <= unsigned(Ton) ELSE '0'; --OK END Behavioral;
  • 71.
    Period<= “00001111” –16clocks Ton <= “00000011” – 4 clocks
  • 72.
  • 73.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; entitygatedClock is Port ( clk : in STD_LOGIC; slowClk1 : inout STD_LOGIC:= '0'; slowClk2 : inout STD_LOGIC:= '0'); end gatedClock; architecture Behavioral of gatedClock is signal tmpCounter1,tmpCounter2: integer :=0; constant timeOut1:integer := 10; constant timeOut2:integer := 4; begin Prescaler: process (clk) begin if(rising_edge(clk)) then if (tmpCounter1 = timeOut1-1) then tmpCounter1 <= 0; else tmpCounter1 <= tmpCounter1 + 1; end if; end if; end process; clk_Slow: process (clk) Begin if(rising_edge(clk)) then if (tmpCounter1 < timeOut1/2) then slowClk1 <= '0'; else slowClk1 <= '1'; end if; end if; end process; p_Clk1: process(slowClk1) begin if(rising_edge(slowClk1)) then if (tmpCounter2 = timeOut2-1) then tmpCounter2 <= 0; else tmpCounter2 <= tmpCounter2 + 1; end if; end if; end process; clk2_Slow: process (slowClk1) Begin if(rising_edge(slowClk1)) then if (tmpCounter2 < timeOut2/2) then slowClk2 <= '0'; else slowClk2 <= '1'; end if; end if; end process; end Behavioral; GATED CLOCK!!
  • 75.
  • 76.
    Timer mod LIBRARY ieee; USEieee.std_logic_1164.ALL; ENTITY timer IS GENERIC( TimeOut_ms : INTEGER := 10; FrecCLK_MHz : INTEGER := 100); PORT(CLK, CLR : IN STD_LOGIC; Q : OUT STD_LOGIC := '0'); END timer; ARCHITECTURE archi OF timer IS SIGNAL ctr_time: INTEGER := 0; CONSTANT TimeOut : INTEGER :=(TimeOut_ms*1000*FrecCLK_MHz) - 1; BEGIN PROCESS (CLK, CLR) BEGIN IF (CLR='1') THEN ctr_time <= 0; -- CLR Asynchronous ELSIF (CLK'event AND CLK='1') THEN IF ctr_time = TimeOut THEN ctr_time <= 0; ELSE ctr_time <= ctr_time + 1; END IF; END IF; END PROCESS; Q <= '1' WHEN ctr_time = TimeOut ELSE '0'; END archi;
  • 78.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; entityClockDivider is Generic (Period_ms: integer := 2); Port ( clk : in STD_LOGIC; clkout : out STD_LOGIC); end ClockDivider; architecture Behavioral of ClockDivider is COMPONENT timer IS GENERIC( TimeOut_ms : INTEGER := 10; FrecCLK_MHz : INTEGER := 100); PORT(CLK, CLR : IN STD_LOGIC; Q : OUT STD_LOGIC := '0'); END COMPONENT; signal inClk : std_Logic := '0'; signal ENABLE : std_logic := '0'; begin Prescaler: timer GENERIC MAP( TimeOut_ms => Period_ms/2,FrecCLK_MHz => 100) PORT MAP( clk => clk, clr => '0‘, Q => ENABLE); process(clk) begin if(rising_edge(clk)) then if(ENABLE = '1') then inClk <= not inClk; end if; end if; end process; clkout <= inClk ; end Behavioral;
  • 80.
  • 81.
    Shift Register ENTITY ShiftReg_NIS GENERIC ( N : INTEGER := 8); PORT ( DATA_IN: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0); INPUT : IN STD_LOGIC; CLK : IN STD_LOGIC; RST: IN STD_LOGIC; LOAD_ENABLE: IN STD_LOGIC; OUTPUT: OUT STD_LOGIC); END ShiftReg_N; ARCHITECTURE Behavioral OF ShiftReg_N IS SIGNAL tmp : STD_LOGIC_VECTOR (N-1 DOWNTO 0) := (OTHERS => '0'); BEGIN PROCESS (CLK) BEGIN IF CLK'event AND CLK='1' THEN IF RST ='1' THEN tmp <= (others => '0'); ELSIF LOAD_ENABLE = '1' THEN tmp <= DATA_IN; ELSE tmp <= INPUT & tmp(N-1 downto 1) ; END IF; END IF; END PROCESS; OUTPUT <= tmp(0); END Behavioral; FOR?
  • 83.
    CRC CAN bus generatorpolynomial Each flipflop represents a single CRC output bit. The leftmost flipflop is the MSB of the CRC http://www.ghsi.de/pages/subpages/Online%20CRC%20Calculation/ G(x) = x15+ x14+ x10+ x8+ x7+ x4+ x3+ x0
  • 84.
    CRC-CAN library IEEE; use IEEE.STD_LOGIC_1164.ALL; entityCAN_CRC15_GEN is Port ( DATA_IN : in STD_LOGIC; CLK : in STD_LOGIC; RESET : in STD_LOGIC; ENABLE : in STD_LOGIC; CRC_O : out STD_LOGIC_VECTOR (14 downto 0)); end CAN_CRC15_GEN; architecture Behavioral of CAN_CRC15_GEN is SIGNAL crc_tmp : STD_LOGIC_VECTOR (14 DOWNTO 0) := (OTHERS => '0'); SIGNAL SINV : STD_LOGIC := '0'; begin SINV <= DATA_IN XOR crc_tmp(14); PROCESS (CLK) BEGIN IF CLK'EVENT AND CLK = '1' THEN IF(RESET='1') THEN crc_tmp <= (OTHERS => '0'); ELSIF ENABLE = '1' THEN crc_tmp(0) <= SINV; crc_tmp(1) <= crc_tmp(0); crc_tmp(2) <= crc_tmp(1); crc_tmp(3) <= crc_tmp(2) XOR SINV; crc_tmp(4) <= crc_tmp(3) XOR SINV; crc_tmp(5) <= crc_tmp(4); crc_tmp(6) <= crc_tmp(5); crc_tmp(7) <= crc_tmp(6) XOR SINV; crc_tmp(8) <= crc_tmp(7) XOR SINV; crc_tmp(9) <= crc_tmp(8); crc_tmp(10) <= crc_tmp(9) XOR SINV; crc_tmp(11) <= crc_tmp(10); crc_tmp(12) <= crc_tmp(11); crc_tmp(13) <= crc_tmp(12); crc_tmp(14) <= crc_tmp(13) XOR SINV; END IF; END IF; END PROCESS; CRC_O <= crc_tmp; end Behavioral;
  • 85.
  • 86.
  • 87.
    Functions • std_logic_arith (std_logic_unsigned, std_logic_signed) –Arithmetic functions (+,-,<,>) for STD_LOGIC, STD_LOGIC_VECTOR and INTEGER • numeric_std – Arithmetic functions for SIGNED, UNSIGNED and INTEGER but NOT for STD_LOGIC • Operated SIGNALS and VARIABLES should be declared as such. – numeric_std preferred.
  • 88.
    numeric_std translation functions FromTo Funtion SLV, UNSIGNED SIGNED SIGNED(From) SIGNED,SLV UNSIGNED UNSIGNED(From) UNSIGNED, SIGNED SLV STD_LOGIC_VECTOR(From) UNSIGNED, SIGNED INTEGER TO_INTEGER(From) NATURAL (INTEGER) UNSIGNED TO_UNSIGNED(From,SIZE) INTEGER SIGNED TO_SIGNED(From,SIZE) TYPE UNSIGNED IS ARRAY (NATURAL range <>) of STD_LOGIC; TYPE SIGNED IS ARRAY (NATURAL range <>) of STD_LOGIC;
  • 89.
    Counter with LOAD libraryieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- preferred -- entity declaration entity counter_load is port ( -- clock, reset ports clock : in std_logic; reset : in std_logic; -- control ports load : in std_logic; -- input ports initial_value : in std_logic_vector(3 downto 0); -- output ports count : out std_logic_vector(3 downto 0) ) ; end counter_load;
  • 90.
    -- architecture declaration architecturecounter_load_beh of counter_load is signal count_i: unsigned(3 downto 0); -- architecture body begin count_proc: process(clock, reset) begin if(reset='0') then count_i <= (others => '0'); elsif(rising_edge(clock)) then if (load = '1') then count_i <= unsigned(initial_value); else count_i <= count_i + 1; end if; end if; end process count_proc; count <= std_logic_vector(count_i); end architecture counter_load_beh;
  • 91.
    -- architecture declaration architecturecounter_ud_beh of counter_load is signal count_i: integer range 0 to 15; -- architecture body begin count_proc: process(clock, reset) begin if(reset='0') then count_i <= 0; elsif(rising_edge(clock)) then if(load = '1') then count_i <= to_integer(unsigned(initial_value)); else count_i <= count_i + 1; end if; end if; end process count_proc; count <= std_logic_vector(to_unsigned(count_i,4)); end architecture counter_ud_beh;
  • 92.
    PWM 4 steps COUNTER MOD‘M’ MUX 4 : 1 PWM_0 PWM_1 PWM_2 PWM_3 THRESHOLD TIMER PWM_Out_i COMPARATOR PWM_Ou S0 S1 CLK RST ENABLE library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity PWM_CuatroNiveles is Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; S : in STD_LOGIC_VECTOR (1 downto 0); enable : in STD_LOGIC; PWM_Out : out STD_LOGIC); end PWM_CuatroNiveles; architecture Behavioral of PWM_CUatroNiveles is -- TODO: Definir el número de pulsos que hay que contar para que transcurra el tiempo indicado si -- cada ciclo de reloj es de 10 ns (100 MHz) constant PWM_0: integer := CALCULAR; --4 ms constant PWM_1: integer := CALCULAR; --8 ms constant PWM_2: integer := CALCULAR; --12 ms constant PWM_3: integer := CALCULAR; --16 ms constant modulo_timer: integer := PWM_3; signal timer:integer := 0; signal threshold:integer; signal PWM_Out_i: STD_LOGIC; begin -- TODO: Contador con reset síncrono a nivel alto y de módulo modulo_timer -- Señal de contaje: timer -- Inputs: clk, rst -- Módulo: modulo_timer contador_temporizador: --TODO: Multiplexor 4 a 1 -- Inputs: PWM_0,PWM_1,PWM_2,PWM_3 -- Output: Threshold -- Selección: S mux: -- TODO: Comparador de menor igual -- Inputs: Timer, Threshold -- Output: PWM_OUT_i -- TODO: Salida con puerta lógica AND -- Inputs: PWM_Out_i, rst, enable -- Output: PWM_Out Salida: end Behavioral;
  • 93.
    .XDC • ## Clocksignal • set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; • create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}]; • ##Switches • set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { S[0] }]; • set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { S[1] }]; • set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { enable }]; • set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { rst }]; • ## LEDs • set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { PWM_Out }];
  • 94.
    PWM MOD 16 1ms step PWM
  • 95.
    LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USEieee.numeric_std.all; -- STD_LOGIC_VECTOR TO INTEGER ENTITY PWM_Mod16 IS PORT( clk: IN std_logic; rst: IN std_logic; setPoint: IN std_logic_vector(3 DOWNTO 0); PWM_out:OUT std_logic); end PWM_Mod16; ARCHITECTURE behavioral OF PWM_Mod16 IS SIGNAL ctr_pre: integer := 0; SIGNAL ctr_pwm: integer := 0; SIGNAL pwm_clk_en:std_logic; CONSTANT Tick_ms: INTEGER := 1; CONSTANT FrecClkMHz:INTEGER := 100; CONSTANT TimeOutPrescaler: INTEGER := Tick_ms * 1000 * FrecClkMHz -1; CONSTANT PWM_Steps: INTEGER := 15; SIGNAL Threshold:integer := 0; BEGIN prescaler: PROCESS (clk) BEGIN IF(rising_edge(clk))THEN IF(rst = '1') THEN ctr_pre<=0; ELSIF ctr_pre = TimeOutPrescaler THEN ctr_pre <= 0; ELSE ctr_pre <= ctr_pre + 1; END IF; END IF; END PROCESS; pwm_clk_en <= '1' WHEN ctr_pre = TimeOutPrescaler ELSE '0'; ResgisterInputs_proc: PROCESS (clk) BEGIN IF(rising_edge(clk)) THEN IF(pwm_clk_en = '1') THEN IF ctr_pwm = PWM_Steps THEN Threshold <= to_integer(unsigned(setPoint)); END IF; END IF; END IF; END PROCESS; -- EXERCISE: define the rest of the circuit END behavioral;
  • 96.
    .XDC ## This fileis a general .xdc for the Nexys4 DDR Rev. C ## To use it in a project: ## - uncomment the lines corresponding to used pins ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project ## Clock signal set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}]; ##Switches set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { setPoint[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0] set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { setPoint[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1] set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { setPoint[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2] set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { setPoint[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3] ## LEDs set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { PWM_out }]; #IO_L18P_T2_A24_15 Sch=led[0]
  • 97.
  • 98.
    LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITYstMachineMoore IS PORT (CLK: IN STD_LOGIC; RST: IN STD_LOGIC; IN0: IN STD_LOGIC; OUTV: OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00"); END stMachineMoore; ARCHITECTURE Behavioral OF stMachineMoore IS TYPE states_t IS (stSTART,stLEFT,stRIGHT); SIGNAL currState: states_t := stSTART; --selfinti SIGNAL nextState: states_t := stSTART; --selfinti BEGIN
  • 99.
    SYNC_PROC: PROCESS (CLK)--just clock BEGIN IF(rising_edge(CLK)) THEN IF(RST = '1') THEN currState <= stSTART; ELSE -- IF ENABLE_STATE_MACHINE = '1' THEN currState <= nextState; -- END IF; END IF; END IF; END PROCESS;
  • 100.
    NEXT_STATE_DECODE: PROCESS(currState,IN0) --Currentstate + all inputs BEGIN nextState <= currState; CASE currState IS WHEN stSTART => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; WHEN stRIGHT => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; WHEN stLEFT => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; END CASE; END PROCESS;
  • 101.
    --or other combinationalstructure OUTPUT_DECODE: PROCESS (currState) --just current state BEGIN CASE currState IS WHEN stSTART => OUTV <= "00"; WHEN stRIGHT => OUTV <= "01"; WHEN stLEFT => OUTV <= "10"; END CASE; END PROCESS; END Behavioral;
  • 102.
    LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITYstMachineMoore IS PORT (CLK: IN STD_LOGIC; RST: IN STD_LOGIC; IN0: IN STD_LOGIC; OUTV: OUT STD_LOGIC_VECTOR(1 DOWNTO 0):="00"); END stMachineMoore; ARCHITECTURE Behavioral OF stMachineMoore IS TYPE states_t IS (stSTART,stLEFT,stRIGHT); SIGNAL currState: states_t := stSTART; --selfinti SIGNAL nextState: states_t := stSTART; --selfinti BEGIN SYNC_PROC: PROCESS (CLK) --just clock BEGIN IF(rising_edge(CLK)) THEN IF(RST = '1') THEN currState <= stSTART; ELSE -- IF ENABLE_STATE_MACHINE = '1' THEN currState <= nextState; -- END IF; END IF; END IF; END PROCESS; NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs BEGIN nextState <= currState; CASE currState IS WHEN stSTART => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; WHEN stRIGHT => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; WHEN stLEFT => IF(IN0 = '1') THEN nextState <= stRIGHT; ELSE nextState <= stLEFT; END IF; END CASE; END PROCESS; OUTPUT_DECODE: PROCESS (currState) --just current state BEGIN CASE currState IS WHEN stSTART => OUTV <= "00"; WHEN stRIGHT => OUTV <= "01"; WHEN stLEFT => OUTV <= "10"; END CASE; END PROCESS; END Behavioral;
  • 104.
  • 105.
    LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITYstMachineMealy IS PORT (CLK: IN STD_LOGIC; RST: IN STD_LOGIC; IN0: IN STD_LOGIC; OUTV: OUT STD_LOGIC); END stMachineMealy; ARCHITECTURE Behavioral OF stMachineMealy IS TYPE states_t IS (stSTART,st1,st0); SIGNAL currState: states_t := stSTART; --selfinit SIGNAL nextState: states_t := stSTART; --selfinit SIGNAL OUTV_in: STD_LOGIC := '0'; BEGIN
  • 106.
    SYNC_PROC: PROCESS (CLK)-- just clock BEGIN IF(rising_edge(CLK)) THEN IF(RST = '1') THEN currState <= stSTART; OUTV<= '0'; ELSE -- IF ENABLE_STATE_MACHINE = '1' THEN currState <= nextState; OUTV <= OUTV_in; -- END IF; END IF; END IF; END PROCESS;
  • 107.
    NEXT_STATE_DECODE: PROCESS(currState,IN0) --Currentstate + all inputs BEGIN nextState <= currState; CASE currState IS WHEN stSTART => IF(IN0 = '1') THEN nextState <= st0; ELSE nextState <= st1; END IF; WHEN st0 => IF(IN0 = '1') THEN nextState <= st1; ELSE nextState <= st0; END IF; WHEN st1 => IF(IN0 = '1') THEN nextState <= st0; ELSE nextState <= st1; END IF; END CASE; END PROCESS;
  • 108.
    OUTPUT_DECODE: PROCESS (currState,IN0) --Current state + all inputs BEGIN CASE currState IS WHEN stSTART => IF IN0 = '1' THEN OUTV_in <= '0'; ELSE OUTV_in <= '1'; END IF; WHEN st0 => IF IN0 = '1' THEN OUTV_in <= '0'; ELSE OUTV_in <= '0'; END IF; WHEN st1 => IF IN0 = '1' THEN OUTV_in <= '1'; ELSE OUTV_in <= '0'; END IF; END CASE; END PROCESS;
  • 109.
    LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITYstMachineMealy IS PORT (CLK: IN STD_LOGIC; RST: IN STD_LOGIC; IN0: IN STD_LOGIC; OUTV: OUT STD_LOGIC); END stMachineMealy; ARCHITECTURE Behavioral OF stMachineMealy IS TYPE states_t IS (stSTART,st1,st0); SIGNAL currState: states_t := stSTART; --selfinti SIGNAL nextState: states_t := stSTART; --selfinti SIGNAL OUTV_in: STD_LOGIC := '0'; BEGIN SYNC_PROC: PROCESS (CLK) -- just clock BEGIN IF(rising_edge(CLK)) THEN IF(RST = '1') THEN currState <= stSTART; OUTV<= '0'; ELSE -- IF ENABLE_STATE_MACHINE = '1' THEN currState <= nextState; OUTV <= OUTV_in; -- END IF; END IF; END IF; END PROCESS; NEXT_STATE_DECODE: PROCESS(currState,IN0) --Current state + all inputs BEGIN nextState <= currState; CASE currState IS WHEN stSTART => IF(IN0 = '1') THEN nextState <= st0; ELSE nextState <= st1; END IF; WHEN st0 => IF(IN0 = '1') THEN nextState <= st1; ELSE nextState <= st0; END IF; WHEN st1 => IF(IN0 = '1') THEN nextState <= st0; ELSE nextState <= st1; END IF; END CASE; END PROCESS; OUTPUT_DECODE: PROCESS (currState, IN0) --Current state + all inputs BEGIN CASE currState IS WHEN stSTART => IF IN0 = '1' THEN OUTV_in <= '0'; ELSE OUTV_in <= '1'; END IF; WHEN st0 => IF IN0 = '1' THEN OUTV_in <= '0'; ELSE OUTV_in <= '0'; END IF; WHEN st1 => IF IN0 = '1' THEN OUTV_in <= '1'; ELSE OUTV_in <= '0'; END IF; END CASE; END PROCESS;
  • 111.
  • 112.
    Stepper Dev. 1a →1 0 0 0 Dev. 1b → 0 0 1 0 Dev. 2a → 0 1 0 0 Dev. 2b → 0 0 0 1 Dev. 1a → 1 1 0 0 Dev. 1b → 0 0 1 1 Dev. 2a → 0 1 1 0 Dev. 2b → 1 0 0 1 2 phases Higher torque 1 phase Full step
  • 113.
    Stepper Dev. 1ª →1 1 0 0 0 0 0 1 Dev. 1b → 0 0 0 1 1 1 0 0 Dev. 2ª → 0 1 1 1 0 0 0 0 Dev. 2b → 0 0 0 0 0 1 1 1 Half step
  • 114.
  • 117.
    Libraries and packages •Default std, work
  • 119.
  • 120.
  • 121.
  • 122.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; entityDebouce is Generic( constant stages:integer := 8); Port ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); end Debouce; architecture Behavioral of Debouce is type State_Type is (LoadNewBit, WaitTimeOut); signal State : State_Type := LoadNewBit; signal DPB, SPB : STD_LOGIC; signal DReg : STD_LOGIC_VECTOR (stages - 1 downto 0); signal ones_Vector : STD_LOGIC_VECTOR (stages - 1 downto 0) := (others => '1'); signal zeroes_Vector : STD_LOGIC_VECTOR (stages - 1 downto 0) := (others => '0'); constant foscMHz : integer := 100; -- twindow constant debounceTimeOutms : integer := 16; -- tsample constant DelayTicks : integer := (debounceTimeOutms / stages * 1000 * foscMHz); begin
  • 123.
    begin process (clk_i) --SHIFTREGISTER variable SDC : integer; begin if (rising_edge(clk_i)) then if(rst_i = '1') then Dreg <= zeroes_Vector; else DPB <= SPB; -- Double latch input signal SPB <= D_i; case State is when LoadNewBit => DReg <= DReg(stages - 2 downto 0) & DPB; SDC := DelayTicks; State <= WaitTimeOut; when WaitTimeOut => SDC := SDC - 1; --Software alike!!! if SDC = 0 then State <= LoadNewBit; end if; when others => State <= LoadNewBit; end case; end if; end if; end process; process(clk_i) --COMPARATOR & RS flip flop begin if(rising_edge(clk_i)) then if(rst_i = '1') then D_o <= '0'; else if DReg = ones_Vector then D_o <= '1'; elsif DReg = zeroes_Vector then D_o <= '0'; end if; end if; end if; end process; end Behavioral;
  • 124.
  • 125.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; entityone_shot is Port ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); end one_shot; architecture Behavioral of one_shot is signal Q1 : std_logic; begin process(clk_i) begin if (rising_edge(clk_i)) then if (rst_i = '1') then Q1 <= '0'; else Q1 <= D_i; end if; end if; end process; D_o <= D_i and (not Q1); end Behavioral;
  • 126.
  • 127.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; ENTITYbutton IS PORT ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); END button; architecture Behavioral of button is COMPONENT one_shot is PORT ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); END COMPONENT; COMPONENT Debouce is Port ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); end COMPONENT; SIGNAL d_ii: STD_LOGIC := '0'; BEGIN d: Debouce PORT MAP( D_i =>D_i, clk_i => clk_i, rst_i => rst_i, D_o => d_ii); o: one_shot PORT MAP( D_i => d_ii, clk_i => clk_i, rst_i => rst_i, D_o => D_o); END Behavioral;
  • 129.
    Timed crosswalk regultedtraffic light • The traffic light should be green for at least 32 s. If a pedestrian asserts the switch before that time elapses, the traffic light will remain green for those 32 s. If that time was over, the pedestraian would not wait. Then, orange light will be on for 5 s. After that, pedestrians will be able to cross safely for 12 s. clk rst PASO PEATONES TEMPORIZADO VerdeC NaranjaC RojoC VerdeP RojoP Pulsador
  • 130.
    Outputs:[VerdeC,NaranjaC,RojoC,VerdeP,VerdeC] stEsperaPulsador stEsperaTimeOut Coches stNaranjaCoches stEsperaTimeOut Peaones to_coches to_naranja to_peatones 1,0,0,0,1 1,0,0,0,10,1,0,0,1 0,0,1,1,0 one_shot debounce TIMER_COCHES TIMER_NARANJA TIMER_PEATONES STATE MACHINE to_naranja to_peatones to_coches pulsador_i Pulsador clk rst rst rst rst rst rst VerdeC NaranjaC RojoC VerdeP RojoP Button
  • 131.
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; --Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; entity PasoSemaforo is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; Pulsador : in STD_LOGIC; VerdeC : out STD_LOGIC; NaranjaC : out STD_LOGIC; RojoC : out STD_LOGIC; VerdeP : out STD_LOGIC; RojoP : out STD_LOGIC); end PasoSemaforo; architecture Behavioral of PasoSemaforo is -- component button IS PORT ( D_i : in STD_LOGIC; clk_i : in STD_LOGIC; rst_i : in STD_LOGIC; D_o : out STD_LOGIC); END component; type PasoSemaforo_t is (stEsperaPulsador,stEsperaTimeOutCoches,stNaranjaCoches,stEs peraTimeOutPeaones); signal EstActual, EstSiguiente : PasoSemaforo_t := stEsperaPulsador; signal timerCoches,timerNaranja,timerPeatones: INTEGER; signal to_coches,to_naranja,to_peatones:STD_LOGIC; signal pulsador_i:STD_LOGIC; constant escala_tiempo:INTEGER:=100000; --ms --constant escala_tiempo:INTEGER:=100000000; --segundos constant timeout_Coches:INTEGER := 32*escala_tiempo-1; constant timeout_Naranja:INTEGER := 5*escala_tiempo-1; constant timeout_Peatones:INTEGER := 12*escala_tiempo-1; begin stEsperaPulsador stEsperaTimeOut Coches stNaranjaCoches stEsperaTimeOut Peaones to_coches to_naranja to_peatones 1,0,0,0,1 1,0,0,0,1 0,1,0,0,1 0,0,1,1,0 one_shot debounce TIMER_COCHES TIMER_NARANJA TIMER_PEATONES STATE MACHINE to_naranja to_peatones to_coches pulsador_i Pulsador clk rst rst rst rst rst rst VerdeC NaranjaC RojoC VerdeP RojoP Button
  • 132.
    PUSLADOR_FILTRADO: button PORTMAP( clk_i => clk, rst_i => rst, D_i => Pulsador, D_o => Pulsador_i ); TIMER_COCHES: process(clk) begin if(rising_edge(clk))then if(rst = '1') then timerCoches <= 0; else if (EstActual = stEsperaTimeOutPeaones) then timerCoches <= 0; else if (timerCoches /= timeout_Coches) then timerCoches <= timerCoches + 1; else timerCoches <= timerCoches; end if; end if; end if; end if; end process; to_coches <= '1' when timerCoches = timeout_Coches else '0'; TIMER_NARANJA: process(clk) begin if(rising_edge(clk))then if(rst = '1') then timerNaranja <= 0; else if (EstActual = stNaranjaCoches) then if (timerNaranja = timeout_Naranja) then timerNaranja <= 0; else timerNaranja <= timerNaranja + 1; end if; else timerNaranja <= 0; end if; end if; end if; end process; to_Naranja <= '1' when timerNaranja = timeout_Naranja else '0'; Component Instantation Count only during certain states TIMER_PEATONES: process(clk) begin if(rising_edge(clk))then if(rst = '1') then timerPeatones <= 0; else if (EstActual = stEsperaTimeOutPeaones) then if (timerPeatones = timeout_Peatones) then timerPeatones <= 0; else timerPeatones <= timerPeatones + 1; end if; else timerPeatones <= 0; end if; end if; end if; end process; to_peatones <= '1' when timerPeatones = timeout_Peatones else '0'; one_shot debounce TIMER_COCHES TIMER_NARANJA TIMER_PEATONES STATE MACHINE to_naranja to_peatones to_coches pulsador_i Pulsador clk rst rst rst rst rst rst VerdeC NaranjaC RojoC VerdeP RojoP Button
  • 133.
    SYNC_PROC: process (clk) begin if(rising_edge(clk)) then if (rst = '1') then EstActual <= stEsperaPulsador; else EstActual <= EstSiguiente; end if; end if; end process; NEXT_STATE_DECODE: process (EstActual,pulsador_i,to_coches, to_naranja,to_peatones) begin EstSiguiente <= EstActual; --default is to stay in current state --insert statements to decode next_state --below is a simple example case (EstActual) is when stEsperaPulsador => if(pulsador_i = '1') then EstSiguiente <= stEsperaTimeOutCoches; end if; when stEsperaTimeOutCoches => if(to_coches = '1') then EstSiguiente <= stNaranjaCoches; end if; when stNaranjaCoches => if(to_naranja = '1') then EstSiguiente <= stEsperaTimeOutPeaones; end if; when stEsperaTimeOutPeaones => if(to_peatones = '1') then EstSiguiente <= stEsperaPulsador; end if; when others=> EstSiguiente <= stEsperaPulsador; end case; end process; OUTPUT_DECODE: process (EstActual) begin case (EstActual) is when stEsperaPulsador => VerdeC <= '1'; NaranjaC <= '0';RojoC<='0';VerdeP<='0';RojoP<='1'; when stEsperaTimeOutCoches => VerdeC <= '1'; NaranjaC <= '0';RojoC<='0';VerdeP<='0';RojoP<='1'; when stNaranjaCoches => VerdeC <= '0'; NaranjaC <= '1';RojoC<='0';VerdeP<='0';RojoP<='1'; when stEsperaTimeOutPeaones => VerdeC <= '0'; NaranjaC <= '0';RojoC<='1';VerdeP<='1';RojoP<='0'; end case; stEsperaPulsador stEsperaTimeOut Coches stNaranjaCoches stEsperaTimeOut Peaones to_coches to_naranja to_peatones 1,0,0,0,1 1,0,0,0,1 0,1,0,0,1 0,0,1,1,0
  • 135.
    Nexys 4 DDR •https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start
  • 137.
  • 138.
    More on FPGAsynthesis • One-process vs 2-process FSM – https://vhdlwhiz.com/n-process-state-machine/ • http://www.rs- online.com/designspark/electronics/nodes/view/type: knowledge-item/slug:how-to-implement-state- machines-in-your-fpga • State machine encoding “Using FPGA in Mission- Critical Systems” Xcell73 pp.16-19 • 10 FPGA Design Techniques you should know – https://forums.xilinx.com/t5/Xcell-Daily-Blog- Archived/Adam-Taylor-thinks-there-are-ten-FPGA-design- techniques-that-you/ba-p/709550
  • 139.
    COLOURED COPY PASTE •COPY in ISE • PASTE IN NotePad++ (Language VHDL) • PlugIns ->NppExport->Copy RTF • Paste in WORD • Copy in WORD • PASTE in PPT (without selecting any text input) entity bies_jk is Port ( clk : in STD_LOGIC; j : in STD_LOGIC; k : in STD_LOGIC; rst : in STD_LOGIC; ce : in STD_LOGIC; q : out STD_LOGIC; qn : out STD_LOGIC); end bies_jk; architecture Behavioral of bies_jk is signal in_q: std_logic := '0'; begin process (clk) begin if rising_edge(clk) then if rst='1' then in_q <= '0'; elsif ce ='1' then if (j='0' and k='0') then in_q <= in_q; elsif (j='0' and k='1') then in_q <= '0'; elsif (j='1' and k='0') then in_q <= '1'; elsif (j='1' and k='1') then in_q <= not (in_q); end if; end if; end if; end process; q <= in_q; qn <= NOT in_q;
  • 140.
    VHDL Libraries and Types WHENELSE WITH SELECT PROCESS IF-THEN-ELSIF-ELSE CASE WHEN FOR Components Testbenches and simulation Updated: 17 October 2023.