ELD129003-Engtelecom (Diário) - Prof. Marcos Moecke
1 Registro on-line das aulas
1.1 Unidade 1 - Aula inicial, Introdução a disciplina
- 1 ENCONTRO
Unidade 1 - Aula inicial, Introdução a disciplina |
---|
|
1.2 Unidade REV - PRIMEIRO CONTATO COM VHDL
- 3 ENCONTROS
Unidade REV - PRIMEIRO CONTATO COM VHDL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
library library_name;
use library_name.package_name.all;
entity entity_name is
[generic (
cons_name1: const_type const_value;
cons_name2: const_type const_value;
...
cons_nameN: const_type const_value);]
[port (
signal_name1: mode signal_type;
signal_name2: mode signal_type;
...
signal_nameN: mode signal_type);]
[declarative_part]
[begin
statement_part]
end [entity] [entity_name];
architecture arch_name of entity_name is
[declarative_part]
begin
statement_part
end [architecture] [arch_name];
Para ilustrar essas instruções utilizaremos o exemplo de um Mux4x1. Um multiplexador digital de N entradas e 1 saída, frequentemente abreviado como MUX N:1, é um circuito digital muito utilizado para rotear sinais digitais. Ele desempenha a função de selecionar uma das entradas para ser encaminhada para a saída com base em um sinal de seleção (ou controle).
Dada a função booleana do MUX4:1 é simples para descreve-lo em VHDL utilizando apenas operadores lógicos. entity mux4x1 is
port
(
-- Input ports
X: in bit_vector (3 downto 0);
Sel : in bit_vector (1 downto 0);
-- Output ports
Y : out bit
);
end entity;
-- Implementação com lógica pura
architecture v_logica_pura of mux4x1 is
begin
Y <= (X(0) and (not Sel(1)) and (not Sel(0))) or
...
end architecture;
No entanto, o MUX4:1 também pode ser descrito utilizando a instrução WHEN-ELSE <optional_label>: <target> <=
<value> when <condition> else
<value> when <condition> else
...
<value> else
<value>;
Warning (13012): Latch ... has unsafe behavior
No caso do MUX4:1 ele poderia ser descrito como: -- Implementação com WHEN ELSE
architecture v_WHEN_ELSE of mux4x1 is
begin
Y <= X(0) when Sel = "00" else
X(1) when Sel = "01" else
X(2) when Sel = "10" else
X(3);
end architecture;
Outra forma de descrever o MUX4:1 seria utilizando a instrução WITH-SELECT <optional_label>: with <expression> select
<target> <=
<value> when <choices>,
<value> when <choices>,
...
<value> when others;
Error (10313): VHDL Case Statement error ...: Case Statement choices must cover all possible values of expression
-- Implementação com WITH SELECT
architecture v_WITH_SELECT of mux4x1 is
begin
with Sel select
Y <= X(0) when "00", -- note o uso da ,
X(1) when "01",
X(2) when "10",
X(3) when others; -- note o uso de others, para todos os demais valores.
-- Não pode ser substituido por "11" mesmo que o signal seja bit_vector.
end architecture;
CONFIGURATION <configuration_name> OF <entity_name> IS
FOR <architecture_name> END FOR;
END CONFIGURATION;
-- Design Unit que associa a architecture com a entity
CONFIGURATION cfg_ifsc OF mux4x1 IS
FOR v_logica_pura END FOR;
-- FOR v_WHEN_ELSE END FOR;
-- FOR v_WITH_SELECT END FOR;
END CONFIGURATION;
Figura 2.1 - Código RTL do mux4x1 v_logica_pura ![]() Figura 2.2 - Código RTL do mux4x1 v_WHEN_ELSE ![]() Figura 2.3 - Código RTL do mux4x1 v_WITH_SELECT ![]()
|
1.3 Unidade 2 - Dispositivos Lógicos Programáveis
- 3 ENCONTROS
1.4 Unidade 3 - Circuitos sequenciais (Implementação com HDL)
- 8 ENCONTROS
Unidade 3 - Circuitos sequenciais (Implementação com HDL) | ||
---|---|---|
[rótulo:] PROCESS [(lista_de_sensibilidade)] [IS]
[parte_declarativa]
BEGIN
afirmação_sequencial;
afirmação_sequencial;
...
END PROCESS [rótulo];
[rótulo:] IF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSIF condição THEN
afirmação_sequencial;
afirmação_sequencial;
...
ELSE
afirmação_sequencial;
afirmação_sequencial;
...
END IF [rótulo];
--Flip Flop tipo D com reset assincrono, sensivel a borda de subida.
process (clock,reset)
begin
if (reset = '1') then
q <= '0';
-- elsif (clock'event and clock = '1') then or
elsif (rising_edge(clock)) then
q <= d;
end if;
end process;
Figura 5.1 - RTL de Flip-flop D de borda de subida, com reset assíncrono ![]() --Flip Flop tipo D com preset assincrono e sinal de enable, sensivel a borda de descida.
process (clock, preset)
begin
if (preset = '1') then
q <= '1';
elsif (falling_edge(clock)) then
if (enable = '1') then
q <= d;
end if;
end if;
end process;
Figura 5.2 - RTL de Flip-flop D de borda de descida, com preset assíncrono e enable ![]()
--Latch tipo D com reset assincrono.
process (enable, reset, d)
begin
if (reset = '1') then
q <= '0';
elsif (enable='1')) then
q <= d;
end if;
end process;
Figura 5.3 - RTL de Latch D de com reset assíncrono e enable ativo alto ![]()
Figura 5.4 - Comparação do Technology Map de um Latch_D (esquerda) com FF_D (direita) ![]()
-- Flip Flop tipo D com reset síncrono sensível a borda de subida.
-- Modifique a descrição para que o reset_ass seja assíncrono e reset_sinc seja síncrono.
-- Note que a função rising_edge(clock) é equivalente a (clock'event and clock'last_value = '0' and clock = '1'))
process (clock, reset)
begin
if (reset = '1') then
q <= '0';
elsif (clock'event and clock'last_value = '0' and clock = '1')) then
q <= d;
end if;
end process;
Figura 5.5 - RTL do Flip-flop D com reset assíncrono e reset síncrono ![]()
Figura 5.6 - RTL do Registrador (de 4 bits) com reset assíncrono ![]() Figura 5.7 - Techonogy Map do Registrador (de 4 bits) com reset assíncrono ![]()
Figura 5.22 - Temporizações de um Flip Flop ![]() Nota: a violação do tempo de setup ou hold leva ao estado de meta-estabilidade, na qual a saída fica temporariamente em um valor indefenido.
Exemplos de contadores com projeto Sincrono.
Figura 5.23 - Modelo de Circuito Sequencial ![]() Figura 5.24 - Tempo de Setup e Fmax ![]() Figura 5.25 - Equações do Tempo de Setup e Fmax (1/Tc(min)) ![]() Figura 5.26 - Equações do Tempo de Hold ![]() Figura 5.27 - Atraso da saída ![]() Exemplos de outros contadores com projeto síncrono.
-- Instrução concorrente FOR GENERATE.
-- Note que neste caso o '''label''' é obrigatório
label: FOR identificador IN faixa GENERATE
[Parte_Declarativa
BEGIN]
Instruções_concorrentes
...
END GENERATE [label];
entity shift_reg is
generic ( N : natural := 4);
port (
clock, reset : in std_LOGIC ;
d_in: in std_LOGIC;
q_out : out std_LOGIC);
end entity;
architecture ifsc_v1 of shift_reg is
signal d: std_logic_vector(N-1 downto 0);
signal q: std_logic_vector(N-1 downto 0);
begin
...
end architecture;
*Implementar um registrador com N FF_D usando a instrução '''FOR GENERATE'''.
Figura 5.8 - Technology Map de Shift Register ![]() Figura 5.9 - Simulação de Shift Register
Instruções do tipo LOOP: LOOP incondicional, FOR-LOOP, WHILE-LOOP, NEXT, EXIT
[rótulo:] LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] FOR identificador IN faixa LOOP
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] WHILE condição LOOP -- Executa as "afirmações enquanto a "condição" for verdadeira
afirmação_sequencial;
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
EXIT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, termina o "LOOP"
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo:] [FOR identificador IN faixa] LOOP
afirmação_sequencial;
NEXT [rótulo] [WHEN condição]; -- Se a "condição" é verdadeira, não executa as linhas até a linha "END LOOP"
-- e incrementa o "identificador".
afirmação_sequencial;
...
END LOOP [rótulo];
[rótulo opcional:] CASE expressão IS
WHEN valor => -- valor único
afirmação_sequencial;
afirmação_sequencial;
...
WHEN valor1 | valor2 | ... | valorN => -- lista de valores
afirmação_sequencial;
afirmação_sequencial;
...
WHEN valor1 TO valor2 => -- faixa de valores
afirmação_sequencial;
afirmação_sequencial;
...
WHEN OTHERS => -- para evitar latches
afirmação_sequencial;
afirmação_sequencial;
...
END CASE;
entity leading_zeros is
generic (N : natural := 8);
port
( ________ : in std_logic_vector(0 to N-1);
count : out integer range 0 to N
);
end entity;
architecture ____ of leading_zeros is
begin
process (data)
variable count : integer ____ 0 to N
begin
count := 0;
for i ___ data'range ____
case data(i) is
when '0' => count := count + 1;
when _____ => exit;
end ___
end ____
zeros <= count;
end process;
end _______;
Figura 5.15 - Simulação do leading_zeros ![]()
Figura 5.16 - Simulação do counting_zeros ![]()
[rótulo:] WAIT UNTIL <condition>;
[rótulo:] WAIT ON sensitivity_list;
[rótulo:] WAIT FOR time_expression;
Figura 5.18 - RTL do contador BCD 00 a 99 ![]() Figura 5.19 - Simulação do contador BCD 00 a 99 ![]()
Implementar um contador BCD de 00 a 99, com parada em qualquer valor MAX_DU. Onde se D = 5, U = 9, implica em contar de 000 até 59 e ficar parado neste valor. A atingir o valor final MAX_DU, uma saída adicional OPA deve ser ativada.
<generate_label>:
if <condition> generate
-- Concurrent Statement(s)
end generate;
Essa instrução é utilizada para a geração condicional de código durante a elaboração. Com isso, partes do projeto são sintetizadas e outras não, dependendo de certas condições ou parâmetros definidos no projeto. Como ela faz parte do grupo de instruções concorrentes, ela não pode ser utilizada dentro de PROCESS, FUNCTION ou PROCEDURE. Para exemplificar, consideramos a situação em que um contador crescente (UP) OU um contador decrescente (DOWN) devem serm utilizados, mas o contador nunca será aplicado nas duas direções de contagem. Neste caso, é possível estabelecer um parâmetro GENERIC, que definirá se a contagem é UP ou DOWN. Analise o código a seguir: entity contador_up_down_if_generate is
generic
(
MIN : natural := 3;
MAX : natural := 21;
UPDOWN : natural := 0 -- 0 => up; 1 => down
);
port
(
clk, rst : in std_logic;
count_out : out integer range MIN to MAX
);
end entity;
architecture ifsc_v1 of contador_up_down_if_generate is
begin
L1: if UPDOWN = 0 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
count_out <= cnt;
end process;
end generate;
L2: if UPDOWN = 1 generate
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
count_out <= cnt;
end process;
end generate;
end architecture;
Se o parâmetro UPDOWN for instanciado com 0, teremos um contador crescente. Caso seja instanciado com 1, o contador será decrescente. Veja a simulação nos dois casos. Figura 5.20 - Simulação do contador UPDOWN com 0 ![]() Figura 5.21 - Simulação do contador UPDOWN com 1 ![]()
entity contador_up_down_two_arch is
generic
(
MIN : natural := 3;
MAX : natural := 21
);
port
(
clk, rst : in std_logic;
count_out : out integer range MIN to MAX
);
end entity;
architecture arch_up of contador_up_down_two_arch is
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
count_out <= cnt;
end process;
end architecture;
architecture arch_down of contador_up_down_two_arch is
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
count_out <= cnt;
end process;
end architecture;
configuration ifsc_cfg of contador_up_down_2arch is
-- for arch_up end for;
for arch_down end for;
end configuration;
entity contador_up_down_pin is
generic
(
MIN : natural := 3;
MAX : natural := 21
);
port
(
clk, rst : in std_logic;
UPDOWN : natural := 1; -- 0 => up; 1 => down
count_out : out integer range MIN to MAX
);
end entity;
architecture ifsc_v1 of contador_up_down_pin is
signal cnt_down, cnt_up : integer range MIN to MAX;
begin
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MIN;
elsif (rising_edge(clk)) then
if cnt = MAX then
cnt := MIN;
else
cnt := cnt + 1;
end if;
end if;
cnt_up <= cnt;
end process;
process (clk, rst)
variable cnt : integer range MIN to MAX;
begin
if rst = '1' then
cnt := MAX;
elsif (rising_edge(clk)) then
if cnt = MIN then
cnt := MAX;
else
cnt := cnt - 1;
end if;
end if;
cnt_down <= cnt;
end process;
count_out <= cnt_up when UPDOWN = 1 else cnt_down;
end architecture;
Ao fazer as mesmas perguntas para a mesma IA, as respostas podem ser diferentes. Por isso, todas respostas de IA deve passar por um processo de curadoria por humanos.
O projeto top_level deve incluir uma entrada BCD de 4 bits e os sinais de controle para o tipo de mostrador (anodo comum ou catodo comum) e a ativação/desativação do zero. entity top_level is
port (
bcd_tl : in std_logic_vector(3 downto 0);
ACn_CC : in std_logic; -- '1' para anodo comum, '0' para catodo comum
Z_OPC : in std_logic; -- '1' para mostrar zero, '0' para ocultar
ssd1 : out std_logic_vector(6 downto 0);
ssd2 : out std_logic_vector(6 downto 0);
ssd3 : out std_logic_vector(6 downto 0);
ssd4 : out std_logic_vector(6 downto 0)
);
end entity;
architecture ifsc of top_level is
component bcd2ssd is
port (
bcd : in std_logic_vector(3 downto 0);
ACn_CC : in std_logic;
Z_OPC : in std_logic;
ssd : out std_logic_vector(6 downto 0)
);
end component;
begin
u1 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '1', Z_OPC => '1', ssd => ssd1);
u2 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '1', Z_OPC => '0', ssd => ssd2);
u3 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '0', Z_OPC => '1', ssd => ssd3);
u4 : bcd2ssd
port map(bcd_tl => bcd, ACn_CC => '0', Z_OPC => '0', ssd => ssd4);
end architecture;
buf_next <= '1' when (r_reg<unsigned(w)) or (w="0000") else '0';
Figura 5.X - RTL do circuito de PWM ![]() Na simulação abaixo, um clock de 50 ps foi utilizado, e o valor da entrada w foi definida como (3, 8, 0, 1, 15) a cada 1600 ps. Note que a largura do pulso da saída pwm_pulse está de acordo com aquela entrada. Figura 5.X - Simulação do circuito de PWM ![]()
|
1.5 Unidade 4 - Maquinas de Estado Finitas
Unidade 4 - Maquinas de Estado Finitas |
---|
Figura 4.1 - Exemplo de diagrama de estados de uma FSM Fig4.1(a) e implementação em hardware da FSM Fig4.2(a) ![]()
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
----------------------------------------------------------
ENTITY < entity_name > IS
PORT (
clk, rst : IN STD_LOGIC;
entradas : IN < data_type > ;
saidas : OUT < data_type >);
END entity;
----------------------------------------------------------
ARCHITECTURE < architecture_name > OF < entity_name > IS
TYPE state IS (A, B, C, ...);
SIGNAL pr_state, nx_state : state;
-- ATTRIBUTE ENUM_ENCODING : STRING; --optional attribute
-- ATTRIBUTE ENUM_ENCODING OF state : TYPE IS "sequential";
-- ATTRIBUTE SYN_ENCODING OF state : TYPE IS "safe";
BEGIN
------Logica Sequencial da FSM:------------
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
pr_state <= A;
ELSIF rising_edge(clk) THEN
-- apenas na borda do "clk" ocorre a mudança de estado da FSM
pr_state <= nx_state;
END IF;
END PROCESS;
------Logica Combinacional da FSM:------------
PROCESS (pr_state, entradas)
BEGIN
------Valores default das saidas------------
saidas <= < valor > ;
CASE pr_state IS
WHEN A =>
-- é necessário um WHEN para definir as "saidas" durante cada estado
-- e analisar as "entradas" para definir o próximo estado
saidas <= < valor > ; -- apenas se diferente do valor default
IF (entradas = < valor >) THEN
nx_state <= B;
...
ELSE
nx_state <= A;
END IF;
WHEN B =>
saidas <= < valor > ; -- apenas se diferente do valor default
-- dependendo das "entradas", pode ser que hajam mais de um estados de destino
IF (entradas = < valor >) THEN
nx_state <= C;
ELSIF (entradas = < valor >) THEN
nx_state <= A;
ELSE
nx_state <= B;
END IF;
WHEN C =>
saidas <= < valor > ; -- apenas se diferente do valor default
-- a passagem para outro estado pode não depender de nenhuma "entrada"
nx_state <= D;
WHEN ...
END CASE;
END PROCESS;
------Seção de Saída (opcional):-------
-- Essa seção visa garantir que a saida new_output esteja sincronizada com o clk.
-- Se isso não for importante, ela pode ser suprimida
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
new_output <= < valor > ;
ELSIF rising_edge(clk) THEN --or falling_edge(clk)
new_output <= output;
END IF;
END PROCESS;
END architecture;
WHEN others =>
nx_state <= <initial_state>;
Figura 7.2 - FSM - Máquina de vendas (diagrama de estados) ![]() Figura 7.3 - FSM - Máquina de vendas (diagrama de estados com default ![]()
Figura 7.4 - FSM - Máquina de vendas (simulação) ![]()
Figura 7.4 - FSM da Máquina de Lavar Roupas ![]()
Figura 4.3 - Diagrama de blocos de um FSM ![]()
Figura 4.4 - Diagrama de estados de um controlador de memória ![]() Figura 4.5 - ASM de um controlador de memória ![]()
library ieee;
use ieee.std_logic_1164.all;
entity mem_ctrl is
port (
clk : in std_logic;
reset : in std_logic;
mem, rw, burst : in std_logic;
oe, we, we_me : out std_logic
);
end entity;
architecture two_seg_arch2 of mem_ctrl is
type mc_state_type is
(idle, read1, read2, read3, read4, write1);
signal state_reg, state_next : mc_state_type;
begin
process (clk, reset)
begin
if (reset = '1') then
state_reg <= idle;
elsif rising_edge(clk) then
state_reg <= state_next;
end if;
end process;
process (state_reg, mem, rw, burst)
begin
oe <= '0';
we <= '0';
we_me <= '0';
case state_reg is
when idle =>
if mem = '1' then
if rw = '1' then
state_next <= read1;
else
state_next <= write1;
we_me <= '1';
end if;
else
state_next <= idle;
end if;
when write1 =>
we <= '1';
state_next <= idle;
when read1 =>
oe <= '1';
if (burst = '1') then
state_next <= read2;
else
state_next <= idle;
end if;
when read2 =>
oe <= '1';
state_next <= read3;
when read3 =>
oe <= '1';
state_next <= read4;
when read4 =>
oe <= '1';
state_next <= idle;
end case;
end process;
end architecture;
Fonte: adaptado de RTL Hardware Desing, P. Chu. Figura 4.6 - RTL do controlador de memória ![]() Figura 4.7 - FSM do controlador de memória ![]()
Na figura abaixo a FSM modelada tem duas saídas Moore ("oe" e "we"), e uma saída Mealy ("we_me"). Note que as saídas do tipo Moore sempre tem a duração de um período de clock, e elas não dependem diretamente de nenhuma entrada, mas são consequência do estado em que se encontra a FSM. No caso da saída Mealy, as entradas afeta diretamente a saída, conforme se pode ver os gliches da entrada "mem" são transmitidas para a saída "we_me". Figura 4.8 - Simulação do controlador de memoria - diferença entre a saída Moore e saída Mealy ![]() Figura 4.9 - Simulação de escritas, leituras simples e leitura em burst no controlador de memoria ![]()
library ieee;
use ieee.std_logic_1164.all;
entity edge_detector1 is
port(
clk, reset: in std_logic;
strobe: in std_logic;
p1: out std_logic
);
end edge_detector1;
architecture moore_arch of edge_detector1 is
type state_type is (zero, up, one);
signal state_reg, state_next: state_type;
begin
-- state register
process(clk,reset)
begin
if (reset='1') then
state_reg <= zero;
elsif (clk'event and clk='1') then
state_reg <= state_next;
end if;
end process;
-- next-state logic
process(state_reg,strobe)
begin
case state_reg is
when zero=>
if strobe= '1' then
state_next <= up;
else
state_next <= zero;
end if;
when up=>
if strobe= '1' then
state_next <= one;
else
state_next <= zero;
end if;
when one =>
if strobe= '1' then
state_next <= one;
else
state_next <= zero;
end if;
end case;
end process;
-- Moore output logic
p1 <= '1' when state_reg=up else
'0';
end moore_arch;
Fonte: RTL Hardware Desing, P. Chu. Figura 4.10 - Simulação do detector de borda - implementação com saídas Moore ![]() Ao simular o detector de borda, percebe-se que o primeiro pulso (140ps) não foi detectado, pois não durou tempo suficiente para ter o estado atualizado no próximo clock. Isso ocorre pois na saída tipo Moore, as mudanças das saídas só acontecem sincronizadas com o clock. Note ainda que os pulsos em p1 tem a duração exata de um período de clock. library ieee;
use ieee.std_logic_1164.all;
entity edge_detector2 is
port(
clk, reset: in std_logic;
strobe: in std_logic;
p2: out std_logic
);
end edge_detector2;
architecture mealy_arch of edge_detector2 is
type state_type is (zero, one);
signal state_reg, state_next: state_type;
begin
-- state register
process(clk,reset)
begin
if (reset='1') then
state_reg <= zero;
elsif (clk'event and clk='1') then
state_reg <= state_next;
end if;
end process;
-- next-state logic
process(state_reg,strobe)
begin
case state_reg is
when zero=>
if strobe= '1' then
state_next <= one;
else
state_next <= zero;
end if;
when one =>
if strobe= '1' then
state_next <= one;
else
state_next <= zero;
end if;
end case;
end process;
-- Mealy output logic
p2 <= '1' when (state_reg=zero) and (strobe='1') else
'0';
end mealy_arch;
Fonte: RTL Hardware Desing, P. Chu. Figura 4.11 - Simulação do detector de borda - implementação com saídas Mealy ![]() Ao simular o detector de borda, percebe-se que o primeiro pulso (140ps) agora foi detectado. Isso ocorre pois na saída tipo Mealy, as mudanças das saídas dependem do estado atual e da entrada, e por isso não são sincronizadas com o clock. Note que agora os pulsos em p1 tem duração variável. |
1.6 Unidade 5 - Metodologia RT (Register Transfer)
Unidade 5 - Metodologia RT (Register Transfer) |
---|
A fonte principal dessa unidade é o capítulo 11 e 12 do livro "RTL Hardware Desing, P. Chu.". É recomendado que os alunos leiam estes capítulos e usem como fonte de consulta.
Figura 4.12 - Diagrama de blocos básico de uma FSMD ![]()
Figura 4.13 - Diagrama ASMD do algoritmo multiplicador L11.1 ![]()
Figura 4.14 - Diagrama ASMD do algoritmo multiplicador L11.7 e 11.8 ![]()
|
2 Avaliações
Durante o semestre serão realizadas 4 avaliações. As avaliações devem ser enviadas pela plataforma Moodle com os arquivos solicitados.
- Data das avaliações
- A1 - : AE3 - Projeto de uma FSM para controle semafórico
- A2 - : AE4 - Projeto de uma FSMD
- AEs - : Média ponderada de (4*AE1 + 15*AE2)/19
- R - Recuperação de A1 a A2 : Novo prazo para entrega das AE3 e AE4.
- Folha de consulta de VHDL
3 Atividade relâmpago (AR)
As atividades relâmpago devem ser entregues no Moodle da disciplina. A não entrega dessas atividades não gera nenhum desconto, apenas geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN.
4 Atividade extra-classe (AE)
A média ponderada das atividades extra-classe será considerada no cálculo do conceito final da UC. A entrega das mesmas será feita pelo Moodle, e cada dia de atraso irá descontar 0,2 na nota da atividade. Muitas dessas atividades também geram pontos de BÔNUS que são adicionados aos conceitos das avaliações A1 a AN. Para os BÔNUS só serão considerados projetos entregues no prazo.
4.1 AE1 - Conhecendo os dispositivos lógicos programáveis
AE1 - Conhecendo os dispositivos lógicos programáveis |
---|
|
4.2 AE2 - Laboratório de programação de FPGA - Relógio HHMMSS
AE2 - Laboratório de programação de FPGA - Relógio HHMMSS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
component div_clk is
generic (fclk2 : natural := 50); -- frequencia para simulacao
port (
clk_in : in std_logic;
rst : in std_logic;
clk_out : out std_logic
);
end component;
component contador_bcd is
generic (max_dezena : natural := 5; max_unidade : natural := 9);
port (
clk: in std_logic;
rst: in std_logic;
fim: out std_logic;
bcd_unidade, bcd_dezena : out std_logic_vector(3 downto 0)
);
end component;
Para esse contador pode ser usado o desenvolvido em aula, mas ele precisa ser modificado para permitir que o clock seja síncrono em todos os flip-flops. Assim é necessário usar um sinal de enable_in para habilitar a contagem durante um período de clock. Também será necessário gerar o sinal de enable_out para habilitar a contagem do próximo contador.
component bcd2ssd is
generic (ac_ccn : natural := 0); -- 1 para mostrador de anodo comum, 0 para mostrador de catodo comum
port (
bcd_in : in std_logic_vector(3 downto 0);
z_opc: in std_logic; -- 1 o zero é mostrado, 0 - o zero é apagado.
ssd_out : out std_logic_vector(6 downto 0)
);
end component;
entity relogio_HHMMSS IS
-- O valor do fclk2 corresponde a metade do periodo do clock de entrada em Hz
generic (fclk2 : natural := 50); -- ao simular o circuito utilize um valor baixo para acelerar a simulaçao
-- generic (fclk2 : natural := 25000000); -- ao implementar no hardware use o valor do clock em Hz
port
(
clk_50MHz_kit: in STD_LOGIC;
rst_SW: in STD_LOGIC; -- use uma chave deslizante para essa função RESET
stop_SW: in STD_LOGIC; -- use uma chave deslizante para essa função PARAR e CONTINUAR
z_opc_SW: in STD_LOGIC; -- use uma chave deslizante para essa função apagar o zero das dezenas
ssd_DS, ssd_DM, ssd_DH: out STD_LOGIC_VECTOR(6 downto 0);
ssd_US, ssd_UM, ssd_UH: out STD_LOGIC_VECTOR(6 downto 0)
);
end entity;
Figura AE2.a - RTL do Relógio Digital de 24 horas ![]()
Figura AE4.b - Simulação funcional do Relógio Digital de 24 horas ![]() Figura AE4.c - Simulação funcional do Relógio Digital de 24 horas - detalhe enable 1sec ![]()
|
4.3 AE3 - Projeto de uma FSM para controle semafórico
AE3 - Projeto de uma FSM para controle semafórico |
---|
Como material auxiliar se sugere consultar o Manual Brasileiro de Sinalização de trânsito: VOLUME V - Sinalização Semafórica do CONTRAN. Outro material resumido sobre o tema pode ser consultado em Sinalização semafórica: definições - Universidade Presbiteriana Mackenzie
Figura AE3.1 - Imagem aérea do Google do cruzamento Shibuya Crossing, em Tóquio, Japão ![]()
Figura AE3.2 - Diagrama do cruzamento Shibuya Crossing ![]()
Figura AE3.3 - Imagem do Google Street do cruzamento Shibuya Crossing ![]()
|
4.4 AE4 - Comparação de Hardware projetado por FSMD e Dataflow
AE4 - Comparação de Hardware projetado por FSMD e Dataflow |
---|
constant zeros : std_logic_vector(N-1 downto 0) := (others => '0');
r <= a * b;
Figura AE4.1 - RTL do multiplicador direto ![]()
-- declare o sinal aux como um vetor de dados do tipo unsigned
type uns_vector is array (0 to 2**W) of unsigned(2*W-1 downto 0);
signal aux : uns_vector;
-- utilize o vetor aux para guardar as sucessivas somas da entrada a_in
-- utilize a entrada b_in para decidir qual dos somas correspode ao resultado.
-- NOTA: este código é muito ineficiente, e está apenas sendo usado para comparar com os códigos desenvolvidos com a metodologia RT;
aux(0) <= to_unsigned(0,2*W);
l1: for k in 0 to 2**W-1 generate
aux(k+1) <= aux(k) + resize(unsigned(a_in),2*W);
end generate;
r <= std_logic_vector(aux(to_integer(unsigned(b_in))));
Figura AE4.2 - RTL do multiplicador por somas sucessivas ![]()
|
5 Referências Bibliográficas: