Tarefa 1. Implementar o cirquito seguinte: botão1 debouncer OR Contador botão2 SDR Aula3 1 botão1 debouncer "C17“; OR Contador botão2 Counter_clock SDR Aula3 2 entity TopLevelModule is Port ( clk reset Button1 Button2 select_display Segments end TopLevelModule; : in STD_LOGIC; : in STD_LOGIC; : in std_logic; : in std_logic; : out STD_LOGIC_VECTOR (3 downto 0); : out STD_LOGIC_VECTOR (7 downto 0)); architecture Behavioral of TopLevelModule is component Debouncer is Port ( clk : in STD_LOGIC; Button : in STD_LOGIC; Debouncer_Button : out STD_LOGIC); end component; component MyCounter Port ( rst clk1Hz clock_enable direction BCD end component; : in STD_LOGIC; : in STD_LOGIC; : in STD_LOGIC; : in STD_LOGIC; : out STD_LOGIC_VECTOR (3 downto 0)); SDR Aula3 3 component Encoder4_7 Port ( BCD Segments end component; signal Counter_clock signal BCD signal Debouncer_Button : in STD_LOGIC_VECTOR (3 downto 0); : out STD_LOGIC_VECTOR (7 downto 1)); : std_logic; : std_logic_vector(3 downto 0); : std_logic; begin Deb Counter Encoder : Debouncer port map (clk,Button1,Debouncer_Button); : MyCounter port map (reset,Counter_clock,'1','1',BCD); : Encoder4_7 port map (BCD,Segments(7 downto 1)); Segments(0) <= '1'; select_display <= "0111"; Counter_clock <= Debouncer_Button or Button2; end Behavioral; SDR Aula3 4 y0,y1 a0 y1,y2 1 a1 x0 not x0 not x1 x3 and x0 y3,y4,y5 y1,y5 a4 not x3 not x0 and not x1 a2 x0 a3 y4 A = {a0,a1,a2,a3,a4}; - conjunto de estados – MOSTRAR NOS DISPLAYS Y = {y0,y1,y2,y3,y4,y5} - conjunto de saídas – MOSTRAR NOS LEDS X = {x0,x1,x2,x3,x4} - conjunto de entradas – ENTRAR A PARTIR DOS INTERRUPTORES SDR Aula3 5 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity FSM_code is Port ( reset : std_logic; X : in STD_LOGIC_VECTOR (3 downto 0); Y : out STD_LOGIC_VECTOR (5 downto 0); state : out integer range 0 to 4; Clock : in STD_LOGIC); end FSM_code; architecture Behavioral of FSM_code is type estado is (a0,a1,a2,a3,a4); signal c_s, n_s : estado; signal Y_c : std_logic_vector(5 downto 0); signal Y_n : std_logic_vector(5 downto 0); SDR Aula3 6 begin process(Clock,reset) begin if reset = '1' then c_s <= a0; Y_c <= (others => '0'); elsif rising_edge(Clock) then c_s <= n_s; Y_c <= Y_n; end if; end process; process(c_s) begin n_s <= c_s; Y_n <= Y_c; case c_s is when a0 => Y_n <= "000011"; n_s <= a1; when a1 => Y_n <= "000110"; if X(0) = '1' then n_s <= a2; else n_s <= a4; end if; SDR Aula3 7 when a2 => Y_n <= "111000"; if X(0) = '1' then n_s <= a2; elsif X(1) = '1' then n_s <= a3; else n_s <= a0; end if; when a3 => Y_n <= "010000"; if X(3) = '0' then n_s <= a4; elsif X(0) = '1' then n_s <= a1; else n_s <= a0; end if; when a4 => Y_n <= "100010"; if X(1) = '1' then n_s <= a3; else n_s <= a0; end if; when others => null; end case; end process; state <= 0 when c_s = a0 else 1 when c_s = a1 else 2 when c_s = a2 else 3 when c_s = a3 else 4 when c_s = a4 else 0; Y <= Y_n; end Behavioral; SDR Aula3 8 Tarefa: Tarefas para aula (7.10.2008): Tarefa 1. Projectar um circuito para fazer contas aritméticas: R1 = Op1 + Op2; R2 = Op1 - Op2; R3 = Op1 * Op2; R4 = Op1 / Op2; Onde: Op1 tem tamanho 2 bits (usa interruptores 1 e 2 da placa) Op2 tem tamanho 2 bits (usa interruptores 3 e 4 da placa) R1 deve aparecer no primeiro display quando carrega no botão1 da placa R2 deve aparecer no segundo display quando carrega no botão2 da placa R3 deve aparecer no terceiro display quando carrega no botão3 da placa R4 deve aparecer no quatro display quando carrega no botão4 da placa SDR Aula3 9 entity TopLevelModule is Port ( clk : in STD_LOGIC; Buttons : in std_logic_vector(3 downto 0); DIP : in std_logic_vector(3 downto 0); select_display : out STD_LOGIC_VECTOR (3 downto 0); Segments : out STD_LOGIC_VECTOR (7 downto 0); sign_LED : out std_logic; divide_by_zero : out std_logic ); end TopLevelModule; architecture Behavioral of TopLevelModule is component MyArithmetic Port ( Operand1 : in std_logic_vector(1 downto 0); Operand2 : in std_logic_vector(1 downto 0); Sum : out std_logic_vector(3 downto 0); difference : out std_logic_vector(3 downto 0); product : out std_logic_vector(3 downto 0); quotient : out std_logic_vector(3 downto 0); sign : out std_logic; divide_by_zero : out std_logic ); end component; component Encoder4_7 Port ( BCD : in STD_LOGIC_VECTOR (3 downto 0); Segments : out STD_LOGIC_VECTOR (7 downto 1)); end component; SDR Aula3 10 signal S : std_logic_vector(3 downto 0); signal D : std_logic_vector(3 downto 0); signal P : std_logic_vector(3 downto 0); signal Q : std_logic_vector(3 downto 0); signal WhichDisplay : std_logic_vector(1 downto 0); signal div : std_logic_vector(22 downto 0) := (others => '0'); ignal BCD : std_logic_vector(3 downto 0); begin Arithmetic : MyArithmetic port map (DIP(3 downto 2),DIP(1 downto 0),S,D,P,Q, sign_LED,divide_by_zero); Encoder : Encoder4_7 port map (BCD,Segments(7 downto 1)); Segments(0) <= '1'; div<= div + 1 when rising_edge(clk); WhichDisplay <= div(16 downto 15); process(WhichDisplay) begin if WhichDisplay ="00" then elsif WhichDisplay ="01" then elsif WhichDisplay ="10" then else end if; end process; select_display <= "1110"; select_display <= "1101"; select_display <= "1011"; select_display <= "0111"; SDR Aula3 11 process(clk) begin if rising_edge(clk) then if (WhichDisplay ="11") and (Buttons(3) = '1') then BCD <= S; elsif (WhichDisplay ="10") and (Buttons(2) = '1') then BCD <= D; elsif (WhichDisplay ="01") and (Buttons(1) = '1') then BCD <= P; elsif (WhichDisplay ="00") and (Buttons(0) = '1') then BCD <= Q; else BCD <= "1010"; end if; else null; end if; end process; end Behavioral; signal S signal D signal P signal Q : std_logic_vector(3 downto 0); : std_logic_vector(3 downto 0); : std_logic_vector(3 downto 0); : std_logic_vector(3 downto 0); Arithmetic : MyArithmetic port map (DIP(3 downto 2),DIP(1 downto 0),S,D,P,Q, sign_LED,divide_by_zero); SDR Aula3 12 Tarefa 3. Implementar o cirquito para divisão: dividendo 0,...,255 divisor 0,...,255 entity TopLevelModule is Port ( clk : in STD_LOGIC; Buttons : in std_logic_vector(3 downto 0); DIP : in std_logic_vector(7 downto 0); select_display : out STD_LOGIC_VECTOR (3 downto 0); Segments : out STD_LOGIC_VECTOR (7 downto 0); divide_by_zero : out std_logic end TopLevelModule; ); LED SDR Aula3 13 entity TopLevelModule is Port ( clk Buttons DIP select_display Segments divide_by_zero end TopLevelModule; : in STD_LOGIC; : in std_logic_vector(3 downto 0); : in std_logic_vector(7 downto 0); : out STD_LOGIC_VECTOR (3 downto 0); : out STD_LOGIC_VECTOR (7 downto 0); : out std_logic ); component MyDivider Port( clk rst Divident Divisor Quotient ResRem divide_by_zero end component; : in std_logic; : in std_logic; : in std_logic_vector(15 downto 0); : in std_logic_vector(15 downto 0); : out std_logic_vector(15 downto 0); : out std_logic_vector(15 downto 0); : out std_logic ); component Encoder4_7 Port ( BCD : in STD_LOGIC_VECTOR (3 downto 0); Segments : out STD_LOGIC_VECTOR (7 downto 1)); end component; SDR Aula3 14 signal WhichDisplay signal div : std_logic_vector(1 downto 0); : std_logic_vector(22 downto 0) := (others => '0'); signal BCD : std_logic_vector(3 downto 0); signal Q signal R : std_logic_vector(15 downto 0); : std_logic_vector(15 downto 0); signal DIP_Divident signal DIP_Divisor : std_logic_vector(15 downto 0); : std_logic_vector(15 downto 0); Entrada 167/28 Q = 5; R = 27 Divisão Encoder SDR Aula3 15 type rom_type is array (0 to 255) of std_logic_vector (11 downto 0); constant ROM : rom_type := ("000000000000","000000000001","000000000010","000000000011","000000000100","000000000101","000000000110","000000000111","000000001000", "000000001001", "000000010000","000000010001","000000010010","000000010011","000000010100","000000010101","000000010110","000000010111","000000011000", "000000011001", "000000100000","000000100001","000000100010","000000100011","000000100100","000000100101","000000100110","000000100111","000000101000", "000000101001", "000000110000","000000110001","000000110010","000000110011","000000110100","000000110101","000000110110","000000110111","000000111000", "000000111001", "000001000000","000001000001","000001000010","000001000011","000001000100","000001000101","000001000110","000001000111","000001001000", "000001001001", "000001010000","000001010001","000001010010","000001010011","000001010100","000001010101","000001010110","000001010111","000001011000", "000001011001", "000001100000","000001100001","000001100010","000001100011","000001100100","000001100101","000001100110","000001100111","000001101000", "000001101001", "000001110000","000001110001","000001110010","000001110011","000001110100","000001110101","000001110110","000001110111","000001111000", "000001111001", "000010000000","000010000001","000010000010","000010000011","000010000100","000010000101","000010000110","000010000111","000010001000", "000010001001", "000010010000","000010010001","000010010010","000010010011","000010010100","000010010101","000010010110","000010010111","000010011000", "000010011001", "000010000000","000100000001","000100000010","000100000011","000100000100","000100000101","000100000110","000100000111","000100001000", "000100001001", "000100010000","000100010001","000100010010","000100010011","000100010100","000100010101","000100010110","000100010111","000100011000", "000100011001", "000100100000","000100100001","000100100010","000100100011","000100100100","000100100101","000100100110","000100100111","000100101000", "000100101001", "000100110000","000100110001","000100110010","000100110011","000100110100","000100110101","000100110110","000100110111","000100111000", "000100111001", "000101000000","000101000001","000101000010","000101000011","000101000100","000101000101","000101000110","000101000111","000101001000", "000101001001", "000101010000","000101010001","000101010010","000101010011","000101010100","000101010101","000101010110","000101010111","000101011000", "000101011001", "000101100000","000101100001","000101100010","000101100011","000101100100","000101100101","000101100110","000101100111","000101101000", "000101101001", "000101110000","000101110001","000101110010","000101110011","000101110100","000101110101","000101110110","000101110111","000101111000", "000101111001", "000110000000","000110000001","000110000010","000110000011","000110000100","000110000101","000110000110","000110000111","000110001000", "000110001001", "000110010000","000110010001","000110010010","000110010011","000110010100","000110010101","000110010110","000110010111","000110011000", "000110011001", "001000000000","001000000001","001000000010","001000000011","001000000100","001000000101","001000000110","001000000111","001000001000", "001000001001", "001000010000","001000010001","001000010010","001000010011","001000010100","001000010101","001000010110","001000010111","001000011000", "001000011001", "001000100000","001000100001","001000100010","001000100011","001000100100","001000100101","001000100110","001000100111","001000101000", "001000101001", "001000110000","001000110001","001000110010","001000110011","001000110100","001000110101","001000110110","001000110111","001000111000", "001000111001", "001001000000","001001000001","001001000010","001001000011","001001000100","001001000101","001001000110","001001000111","001001001000", "001001001001", "001001010000","001001010001","001001010010","001001010011","001001010100","001001010101" ); begin process(clk) 000101110100" 174 SDR Aula3 16 begin Ler operandos process(clk) begin if rising_edge(clk) then if Buttons = "0010" then DIP_Divident <= "00000000" & DIP; elsif Buttons = "0100" then DIP_Divisor(15 downto 8) <= DIP; DIP_Divisor(7 downto 0) <= (others => '0'); else null; end if; signal WhichDisplay : std_logic_vector(1 downto 0); end if; : std_logic_vector(22 downto 0) := (others => '0'); end process; signal div div<= div + 1 when rising_edge(clk); WhichDisplay <= div(16 downto 15); process(WhichDisplay) begin if WhichDisplay ="00" then elsif WhichDisplay ="01" then elsif WhichDisplay ="10" then else end if; end process; select_display <= "1110"; select_display <= "1101"; select_display <= "1011"; select_display <= "0111"; SDR Aula3 17 Divider : MyDivider port map (clk, Buttons(0),DIP_Divident,DIP_Divisor,Q,R,divide_by_zero); Encoder : Encoder4_7 port map (BCD,Segments(7 downto 1)); Segments(0) <= '1'; process(clk) begin if rising_edge(clk) then if (WhichDisplay ="11") then BCD <= "0000"; elsif (WhichDisplay ="10") then if Buttons = "0010" then BCD <= ROM(conv_integer(DIP_Divident))(11 downto 8); elsif Buttons = "0100" then BCD <= ROM(conv_integer(DIP_Divisor(15 downto 8)))(11 downto 8); elsif Buttons = "1000" then BCD <= ROM(conv_integer(R))(11 downto 8); else BCD <= ROM(conv_integer(Q))(11 downto 8); end if; elsif (WhichDisplay ="01") then if Buttons = "0010" then BCD <= ROM(conv_integer(DIP_Divident))(7 downto 4); elsif Buttons = "0100" then BCD <= ROM(conv_integer(DIP_Divisor(15 downto 8)))(7 downto 4); elsif Buttons = "1000" then BCD <= ROM(conv_integer(R))(7 downto 4); else BCD <= ROM(conv_integer(Q))(7 downto 4); end if; else if Buttons = "0010" then BCD <= ROM(conv_integer(DIP_Divident))(3 downto 0); elsif Buttons = "0100" then BCD <= ROM(conv_integer(DIP_Divisor(15 downto 8)))(3 downto 0); elsif Buttons = "1000" then BCD <= ROM(conv_integer(R))(3 downto 0); else BCD <= ROM(conv_integer(Q))(3 downto 0); end if; end if; else null; end if; end process; SDR Aula3 18 end Behavioral; entity MyDivider is Port ( clk : in std_logic; rst : in std_logic; Divident : in std_logic_vector(15 downto 0); Divisor : in std_logic_vector(15 downto 0); Quotient : out std_logic_vector(15 downto 0); ResRem : out std_logic_vector(15 downto 0); divide_by_zero: out std_logic ); end MyDivider; architecture Behavioral of MyDivider is type state_type is (a0,a1,a2,a3,a4,a5); signal FSMstate, FSMnext_state : state_type; signal local_quotient signal local_divisor : std_logic_vector(15 downto 0); : std_logic_vector(15 downto 0); begin divide_by_zero <= '1' when Divisor = "0000000000000000" else '0'; SDR Aula3 19 process(clk,rst) begin if rst = '1' then FSMstate <= a0; elsif rising_edge(clk) then FSMstate <= FSMnext_state; end if; end process; process(clk,rst) variable remainder : std_logic_vector(15 downto 0); variable index : integer range 0 to 9; begin if rst = '1' then local_quotient <= (others => '0'); local_divisor <= Divisor; remainder := Divident; index := 0; SDR Aula3 20 elsif falling_edge(clk) then case FSMstate is when a0 => FSMnext_state <= a1; local_quotient <= (others => '0'); local_divisor <= Divisor; remainder := Divident; index := 0; when a1 => remainder := remainder-local_divisor; if (remainder(15) = '1')then FSMnext_state <= a2; else FSMnext_state <= a3; end if; when a2 => FSMnext_state <= a4; remainder := remainder+local_divisor; local_quotient <= local_quotient(14 downto 0) & '0'; when a3 => FSMnext_state <= a4; local_quotient <= local_quotient(14 downto 0) & '1'; when a4 => local_divisor <= '0' & local_divisor(15 downto 1); index := index+1; if (index = 9) then FSMnext_state <= a5; else FSMnext_state <= a1; end if; when a5 => FSMnext_state <= a0; Quotient <= local_quotient; ResRem <= remainder; when others => null; end case; else null; end if; end process; SDR Aula3 end Behavioral; 21 Acabar exemplos da aula anterior. Fazer experiências com projectos considerados na aula Organização: 1. Cada grupo vai receber tarefas 1, 2, 3, etc. No final da aula (até às 19h) devem enviar projectos implementados para endereço [email protected]. A nota da avaliação será calculada com base no número de tarefas implementadas e número de erros. 2. O tempo de trabalho é de 2.5 horas. Os primeiros 20 minutos da aula vão ser usados para explicar o trabalho. Os últimos 10 minutos - para enviar os projectos. O tempo de trabalho é 16h20m-18h50m. Depois das 19h00m não será aceite nenhuma tarefa. SDR Aula3 22 Pode encontrar o código aqui ou utilizar códigos dos meus exemplos (por exemplo, para máquina de estados finitos ou para circuitos aritméticos) Durante avaliação não pode fazer perguntas SDR Aula3 23