A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

VHDL Very High Speed Integrated Circuit Hardware Description Language Prof. Eduardo Todt 2008.

Apresentações semelhantes


Apresentação em tema: "VHDL Very High Speed Integrated Circuit Hardware Description Language Prof. Eduardo Todt 2008."— Transcrição da apresentação:

1 VHDL Very High Speed Integrated Circuit Hardware Description Language Prof. Eduardo Todt 2008

2 Introdução Linguagem para descrição de sistemas digitais Evoluiu para simulação, análise, síntese Origem: meados década de 80, US Department of Defense e IEEE Norma IEEE 1076-1993, 2000, 2002 Outras linguagens: VERILOG, SystemC, ABEL –VHDL predomina na Europa, VERILOG E.U.A.

3 Níveis de abstração Moraes & Calazans 2006

4 Estrutura de uma descrição VHDL VHDL entity Interface (entity declaration) Body (architecture) sequential, combinational, Processes, subprograms ports entity NAME_OF_ENTITY is [generic generic_declarations);] port (signal_names: mode type; signal_names: mode type; : signal_names: mode type); end [NAME_OF_ENTITY] ; -- exemplo de entity entity alarme is port ( porta, identificado: in std_logic; sirene: out std_logic); end alarme;

5 Entity Entity define interfaces e o nome de um objeto entity NAME_OF_ENTITY is [generic generic_declarations);] port (signal_names: mode type; signal_names: mode type; : signal_names: mode type); end [NAME_OF_ENTITY] ; port: interfaces mode: in | out | buffer | inout type: bit | bit_vector | std_logic | std_logic_vector | boolean | integer | real | character | time |... std_logic tem 9 valores (U,Z,X,0,1,W,L,H,-) definidos em std_logic_1164 package bit tem valores 0 ou 1

6 Declaração generic generic ( constant_name: type [:=value] ; : constant_name: type [:=value] ); Define constantes locais, em geral para tempo (delay de portas) e tamanho de barramentos e registradores

7 Architecture Architecture especifica operação e implementação * uma entidade pode ter várias arquiteturas associadas architecture architecture_name of NAME_OF_ENTITY is -- Declarations -- components declarations -- signal declarations -- constant declarations -- function declarations -- procedure declarations -- type declarations : begin -- Statements : end architecture_name;

8 Modelo comportamental architecture behavioral of alarme is begin sirene <= (porta and not identificado); end behavioral; ---------------------------------------------------------------- entity XNOR2 is port (A, B: in std_logic; Z: out std_logic); end XNOR2; architecture behavioral_xnor of XNOR2 is signal X, Y: std_logic; begin X <= A and B; Y <= (not A) and (not B); \ 3 comandos concorrentes Z <= X or Y; / End behavioral_xnor;

9 Modelo estrutural architecture structural of alarme is -- declarações de tipos de componentes utilizados component AND2 port (in1, in2: in std_logic; out1: out std_logic); end component; component NOT1 port (in1: in std_logic; out1: out std_logic); end component; -- declaração de sinal para interconexão signal n_identificado: std_logic; begin -- instanciação dos componentes utilizados e sinais de ligação U0: NOT1 port map (identificado, n_identificado); U1: AND2 port map (porta, n_identificado, sirene); end structural;

10 Associação posicional x explícita posicional component AND2 port (in1, in2: in std_logic; out1: out std_logic); end component; U1: AND2 port map (porta, n_identificado, sirene); explícita component AND2 port (in1, in2: in std_logic; out1: out std_logic); end component; U1: AND2 port map (in1 => porta, in2=> n_identificado, out1=> sirene);

11 Library library ieee; use ieee.std_logic_1164.all; -- tipos padrão use ieee.std_logic_arith.all; -- funções aritméticas, conversão de tipos e comparações para signed, unsigned, integer, std_ulogic, std_logic and std_logic_vector use ieee.std_logic_unsigned.all; -- idem para unsigned use ieee.std_logic_signed.all; -- idem para signed use ieee. std_logic_misc. all; -- tipos e constantes adicionais overload de operadores, como + permite operações com vetores de bits all indica que são utilizados todos elementos, poderia ser especificado algum

12 Package encapsulam declarações para serem compartilhadas podem ter declarações e opcionalmente um corpo -- Package declaration package name_of_package is package declarations end package name_of_package; -- Package body declarations package body name_of_package is package body declarations end package body name_of_package;

13 Package Moraes & Calazans 2006

14 Package library ieee, my_func; use ieee.std_logic_1164.all; use my_func.basic_func.all; my_func é a biblioteca criada (.vhdl) basic_func é o nome de um conjunto declaração e corpo definidos biblioteca do usuário (default): work – contém todos objetos definidos no projeto

15 Elementos de VHDL identificadores –caracteres A-Z, a-z, 0-9 e underscore –case insensitive –extended identifiers: com ´\´, case sensitive, admitem caracteres especiais. Ex: \input #1\, \BUS:\data\ keywords: abs, all, and, assert, begin, not, case, if, mod, not, or, out, select, then, use, when, xor,...

16 Elementos de VHDL números –integer literals: 12, 256E3, 12E+6 –real literals: 1.2, 256.24, 3.14E-2 –base 2: 2#1010# –base 16: 16#1a# –undescores são ignorados: 2#1010_1100_0011# –fortemente tipado: integer 1, real 1, bit 1 são diferentes

17 Elementos de VHDL caracteres, strings, strings de bits –caractere: A –string de caracteres: abracadabra –bit strings b10110010 x1ff0

18 Elementos de VHDL constantes constant list_of_name_of_constant: type [ := initial value] ; constant DELAY: time := 5 ns; constant DATA_BUS: integer:= 32; sinais –declarados fora de processos –signal list_of_signal_names: type [ := initial value] ; signal clock: std_logic; –sinais são atribuídos após um delay: SUM <= (A xor B) after 2 ns; entrada <= 0, 1 after 2ns, 0 after 10ns, 1 after 15 ns; –são atualizados no final de processos ou em wait variáveis –são atualizadas imediatamente –devem ser declaradas dentro de processos –variable list_of_variable_names: type [ := initial value] ; variable CTL_BIT: bit :=0; –atribuição: Variable_name := expression; soma:= 120;

19 Signals x Variables architecture var of teste is signal trigger, soma: integer := 0; begin process variable var1: integer :=1; variable var2: integer :=2; variable var3: integer :=3; begin wait on trigger; var1 := var2; var2 := var1 + var3; var3 := var2; soma <= var1 + var2 + var3; end process; end var;

20 Signals x Variables architecture sig of teste is signal trigger, soma: integer := 0; signal sig1: integer :=1; signal sig2: integer :=2; signal sig3: integer :=3; begin process begin wait on trigger; sig1 <= sig2; sig2 <= sig1 + sig3; sig3 <= sig2; soma <= sig1 + sig2 + sig3; end process; end sig;

21 Signals x Variables no exemplo com variáveis a avaliação é seqüencial, resultando em 12 no exemplo com sinais, a avaliação é concorrente resultando em 6 todos sinais são atualizados delta time depois do sinal trigger, ao final de processos

22 Mais sobre sinais e variáveis podem ser especificados intervalo e valor inicial –variable alunos: integer range 1 to 60 := 1; –signal alunos: integer range 1 to 60 := 1; –signal flag: std_logic := 0; sinais em geral são para comunicação entre módulos sinais podem ser declarados em entity, architecture ou package sinais não podem ser declarados em processos, mas podem ser inicializados nestes signal byte: std_logic_vector (7 downto 0); byte 1, 5 downto 2 => 1, others => 0);

23 Tipos de dados bit: 0 ou 1 bit_vector: 0011, x1f00,... boolean: true ou false real integer character: a, 0, ou string abcd physical: ms, ps, mV, sec, min,... intervalos: –integer range 1 to 10 –integer range 10 downto 1 –sem range significa todos valores possíveis –<> significa declaração postergada do intervalo enumerações –type estados is (idle, running, halt); –type octal is (0, 1, 2, 3, 4, 5, 6, 7); –type oper is (load, store, add, sub);

24 Arrays coleção de elementos de mesmo tipo –type array_name is array (indexing scheme) of element_type; type WORD1 is array (15 downto 0) of std_logic; type WORD2 is array (0 to 15) of std_logic; type FRAME1 is array (0 to 7) of integer; type MEMORY is array (address) of WORD1; –preenchimento de array: type a is array (1 to 4) of character; posicional: (l', e', s', s') por nome: (1 => l', 3 => s', 2 => e', 4 => s') valores default: (l', e', others => s)

25 Arrays multidimensionais type MATRIX3X2 is array (1 to 3, 1 to 2) of integer; variable DATA_ARRAY: MATRIX3X2 := ((1,2), (2,3), (4,6)); 1 2 2 3 4 6

26 Records coleção de elementos que podem ser de tipos distintos type name is record identifier :subtype_indication; : identifier :subtype_indication; end record; type FRAME is record flag : boolean; source : bit_vector(7 downto 0); dest : bit_vector(7 downto 0); data: bit_vector (31 downto 0); end record; signal A, B: FRAME; A.dest = 1100_0011;

27 Tipo padrão std_ulogic tipo não resolvido (indefinido em caso de conflitos) 9 valores std_logic_1164 package type STD_ULOGIC is ( U,-- uninitialized X,-- forcing unknown 0,-- forcing 0 1,-- forcing 1 Z,-- high impedance W,-- weak unknown L,-- weak 0 H.-- weak 1 -);-- dont care

28 Tipo padrão std_logic tipo resolvido tipo mais comumente utilizado em descrições de hardware std_logic_1164 package SUBTYPE std_logic IS resolved std_ulogic; TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic; ------------------------------------------------------------------- -- resolution function ------------------------------------------------------------------- CONSTANT resolution_table : stdlogic_table := ( -- --------------------------------------------------------- -- | U X 0 1 Z W L H - | | -- --------------------------------------------------------- ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X | ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 | ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 | ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z | ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W | ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L | ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - | );

29 Conversões de tipos std_logic_1164 package std_ulogic to bitto_bit(expression) std_logic_vector to bit_vectorto_bitvector(expression) std_ulogic_vector to bit_vectorto_bitvector(expression) bit to std_ulogicTo_StdULogic(expression) bit_vector to std_logic_vectorTo_StdLogicVector(expression) bit_vector to std_ulogic_vectorTo_StdUlogicVector(expression) std_ulogic to std_logic_vectorTo_StdLogicVector(expression) std_logic to std_ulogic_vectorTo_StdUlogicVector(expression) IEEE std_logic_unsigned e std_logic_arith possuem conversão entre inteiros e std_logic_vector e vice-e-versa, além de overload de operadores. Com isto pode-se realizar operações aritméticas com vetores de bits.

30 Atributos de sinais signal_nameevent – if (CLOCKevent and CLOCK=1) then … scalar_typelow scalar_typehigh scalar_typeleft scalar_typeright...

31 Operadores Van der Spiegel, 2006 Ordem de precedência: classe 7 (maior) para classe 1 (menor) Operadores de mesma classe: esquerda para direita na expressão Parêntesis para alterar ordem

32 Comandos seqüenciais comandos seqüenciais são utilizados em processos, funções e procedimentos um processo é um comando concorrente, mas os comandos dentro do mesmo são executados seqüencialmente [process_label:] process [ (sensitivity_list) ] [is] [ process_declarations] begin list of sequential statements such as: signal assignments variable assignments case statement exit statement if statement loop statement next statement null statement procedure call wait statement end process [process_label];

33 Comandos seqüenciais atribuições de variáveis são restritas ao escopo dos processos e são seqüenciais alteração em um sinal na sensitivity list ocasiona execução imediata do processo se não há sensitivity list é necessário incluir um wait para que o processo interrompa não é possível ter juntos sensitivity list e wait no mesmo processo variáveis são declaradas no processo antes do begin

34 Exemplo de processo: FF D library ieee; use ieee.std_logic_1164.all; entity FlipFlopD is port (clk, clear, D: in std_logic; Q: out std_logic); end FlipFlopD; architecture comportamental of FlipFlopD is begin process (clk, clear) begin if (clear = 1) then Q <= 0; elsif (clkevent and clk = 1) then Q <= D; end if; end process; end comportamental;

35 Testbench para FF D entity FFD_tb is end; architecture teste of FFD_tb is signal D_tb, clear_tb, Q_tb: std_logic; signal clock_tb: std_logic:='0'; component FlipFlopD is port(clk, clear, D: in std_logic; Q: out std_logic); end component; begin F1: FlipFlopD port map(clock_tb,clear_tb,D_tb, Q_tb); D_tb <= '0', '1' after 50 ns, '0' after 100 ns; clock_tb <= not clock_tb after 25 ns; clear_tb <= '1', '0' after 60 ns; end;

36 Comando if if condition then sequential statements [elsif condition then sequential statements ] [else sequential statements ] end if; if S1=0 and S0=0 then Z <= A; elsif S1=0 and S0=1 then Z <= B; elsif S1=1 and S0=0 then Z <= C; elsif S1=1 and S0=1 then Z <= D; end if;

37 Comando case case expression is when choices => sequential statements when choices => sequential statements -- branches are allowed [ when others => sequential statements ] end case; choices ::= choice { | choice } choice ::= simple_expression | discrete_range | element_simple_name | others

38 Comando case entity MUX_4_1 is port ( SEL: in std_logic_vector(2 downto 1); A, B, C, D: in std_logic; Z: out std_logic); end MUX_4_1; architecture behav_MUX41 of MUX_4_1 is begin PR_MUX: process (SEL, A, B, C, D) begin case SEL is when 00 => Z <= A; when 01 => Z <= B; when 10 => Z <= C; when 11 => Z <= D; when others => Z <= X; end case; end process PR_MUX; end behav_MUX41

39 Comando case case element_colour is when red => -- escolha simples statements for red; when green | blue => -- ou statements for green or blue; when orange to turquoise => -- intervalo statements for these colours; end case; case opcode is when X"00" => perform_add; when X"01" => perform_subtract; when others => signal_illegal_opcode; end case Moraes & Calazans 2006

40 basic loop [ loop_label :] loop sequential statements [next [label] [when condition]; [exit [label] [when condition]; end loop [ loop_label];

41 basic loop entity COUNT31 is port ( CLK: in std_logic ; COUNT: out integer); end COUNT31; architecture behav_COUNT of COUNT31 is begin P_COUNT: process variable intern_value: integer :=0; begin COUNT <= intern_value; loop wait until CLK=1; intern_value:=(intern_value + 1) mod 32; COUNT <= intern_value; end loop; end process P_COUNT; end behav_COUNT;

42 while loop [ loop_label :] while condition loop sequential statements [next [label] [when condition]; [exit [label] [when condition]; end loop[ loop_label ]; while index < length and str(index) /= ' ' loop index := index + 1; end loop;

43 Comandos de loop [ loop_label :]iteration_scheme loop sequential statements [next [label] [when condition]; [exit [label] [when condition]; end loop [loop_label]; next termina a iteração corrente exit encerra o loop

44 for loop [ loop_label :] for identifier in range loop sequential statements [next [label] [when condition]; [exit [label] [when condition]; end loop[ loop_label ]; identifier é declarado pelo próprio loop e é válido somente no escopo do loop; seu valor não pode ser atribuído dentro do loop range: integer_expression to integer_expression integer_expression downto integer_expression

45 Exemplo com for loop function conv (byte : word8) return integer is variable result : integer := 0; variable k : integer := 1; begin for index in 0 to 7 loop if ( std_logic(byte(index))='1') then result := result + k; end if; k := k * 2; end loop; return result; end conv ; Moraes & Calazans 2006

46 Comando wait pára um processo até que um evento ocorra wait until condition; -- algums sistemas só suportam este wait for time expression; wait on signal; wait; wait until signal = value; wait until signalevent and signal = value; wait until CLKevent and CLK=1; -- \ são wait until CLK=1; -- / idênticos! ** comportamento do if CLK=´1´ é distinto....

47 Comando null fazer nada útil em case statement case controller_command is when forward => engage_motor_forward; when reverse => engage_motor_reverse; when idle => null; end case;

48 Funções Funções executam comandos seqüenciais e retornam um valor como o valor da função. Funções não alteram seus parâmetros formais. function identifier [ ( formal parameter list ) ] return return_type ; function random return float ; function is_even (N: integer) return boolean ; parâmetros separados por ;

49 Estruturas concorrentes atribuição de sinais A <= B + C; E <= B + D; atribuição de sinais com escolha Target_signal <= expression when Boolean_condition else expression when Boolean_condition else : expression;

50 Estruturas concorrentes atribuição de sinais com seleção with choice_expression select target_name <= expression when choices, : target_name <= expression when choices;

51 Estruturas concorrentes A escolha pode ser mais de um valor ou um range: target <= value1 when 000, value2 when 001 | 011 | 101, value3 when others;

52 Funções function identifier [ ( formal parameter list ) ] return return_type is [declarations] begin sequential statement(s) return some_value; end function identifier; function raiz_quadrada(N: float) return float is variable aux: float; begin -- cálculo da raiz quadrada return aux; end function raiz_quadrada;

53 Procedimentos Procedimentos executam comandos seqüenciais e retornam valores em objetos globais ou por meio dos parâmetros formais Quando colocados em um package, a declaração fica na parte de declaração do package e a implementação no body do package

54 Procedimentos procedure identifier [ ( formal parameter list ) ] ; procedure open_door ; procedure build ( A : in integer; B : inout signal bit_vector; C : out real; D : file ) ;

55 Procedimentos procedure identifier [ ( formal parameter list ) ] is [declarations] begin sequential statement(s) end procedure identifier ;

56 Moraes & Calazans 2006

57 Codificador 7 segmentos b g a c e f d –Em um codificador a saída é uma função combinacional da entrada. –O comando with é utilizado para atribuir um dado valor a um sinal, em função de um sinal de controle. Relacione o estado dos 7 segmentos ´DISPB´ com o estado do número binário ´showb´ Moraes & Calazans 2006

58 Codificador com prioridade Em um codificador com prioridade se o bit menos significativo for 1 a saída é ´0´, se o bit seguinte for 1, independentemente do anterior, a saída é ´1´; e assim sucessivamente. Exemplo ( s(3) tem maior prioridade ) : Y <=11" when s(3) = 1 else 10when s(2) = 1 else 01when s(1) = 1 else 00; Importante haver condição default em atribuições e estruturas similares: NÃO HAVENDO ESTA CONDIÇÃO IMPLICA EM HAVER MEMORIZAÇÃO DO SINAL - diferente de software! (warning latch inferred) Moraes & Calazans 2006

59 Decodificador –decodificador é utilizado basicamente para acionar uma saída em função de um determinado endereço –Mesma construção que o codificador –Exemplo para um decodificador 3 8 with endereço select saída <="00000001" when "000", "00000010" when "001", "00000100" when "010", "00001000" when "011", "00010000" when "100", "00100000" when "101", "01000000" when "110", "10000000" when "111"; Moraes & Calazans 2006

60 MUX 2x1 entity MUX_2x1 is port (sel, A, B: in std_logic; Z: out std_logic); end MUX_2x1; architecture comport of MUX_2x1 is begin P1: process (sel, A, B) begin if (not sel) then Z <= A; else Z <= B; end if; end process P1; end comport;

61 MUX 4x1 entity MUX_4x1 is port(sel: in std_logic_vector(1 downto 0); A, B, C, D: in std_logic; Z: out std_logic); end MUX_4x1; architecture comport of MUX_4x1 is begin process (sel, A, B, C, D) begin case sel is when 00 => Z <= A; when 01 => Z <= B; when 10 => Z <= C; when 11 => Z <= D; when others => Z <= X; end case; end process; end comport;

62 MUX 2x1 concorrente entity MUX_2x1 is port (sel, A, B: in std_logic; Z: out std_logic); end MUX_2x1; architecture comport of MUX_2x1 is begin Z <= A when sel=0 else B; end comport ;

63 MUX 2x1 concorrente entity MUX_2x1 is port (sel, A, B: in std_logic; Z: out std_logic); end MUX_2x1; architecture comport of MUX_2x1 is begin with sel select Z <= A when 0, B when 1; end comport ; todos casos devem ser cobertos, pode ser usado others

64 Mais um mux Saida <=In0 when 0 | 1, In1 when 2 to 5,In2 when 6, In3 when 7, 'Z' when others;

65 ULA (1) outalu_int <= opB when op_alu=st else opA when op_alu=mov else opA and opB when op_alu=and_i else opA or opB when op_alu=or_i else opA xor opB when op_alu=xor_i else opB(15 downto 8) & opA(7 downto 0) when op_alu=ldli else opA - opBwhen op_alu=sub else not opA when op_alu=not_i else opA(14 downto 0) & '0' when op_alu=sl else '0' & opA(15 downto 1) when op_alu=sr else opB + apA; Moraes & Calazans 2006

66 ULA (2) process(M,cin,OPCODE,OPERA,OPERB) begin if (M='1') then -- modo 1 é lógico case OPCODE is when "0000" => saida <= not(OPERA); when "0001" => saida <= not(OPERA and OPERB); when "0010" => saida <= (not(OPERA)) or OPERB; when "0011" => saida <= "0001";........ continuam as outras operações end case; else-- modo 0 é aritmético case OPCODE is when "0000" => tempA <= OPERA; tempB <= OPERB; when "0001" => tempA <= not OPERA;tempB <= OPERB; when "0010" =>tempA <= OPERA; tempB <= "1111";........ continuam as outras operações end case; SUM(tempA, tempB, cin, saida, C4); end if; end process; Moraes & Calazans 2006

67 Registrador –registradores são basicamente sinais declarados em processos com sinal de sincronismo (exemplo: clock). Para efeito de síntese e simulação, é aconselhável introduzir um reset assíncrono. process (clock, reset) begin if reset = '1' then reg 0); -- portável; elsif clock 'event and clock='1' then reg <= barramento_A; end if; end process; 1) Como introduzir um sinal de enable no registrador, para habilitar a escrita? 2) Como implementar um registrador tri-state controlado por um sinal hab? Moraes & Calazans 2006

68 –Registrador com largura de palavra parametrizável, com ce: library.... entity regnbit is generic(N : integer := 16); port(ck, rst, ce : in std_logic; D : in STD_LOGIC_VECTOR (N-1 downto 0); Q : out STD_LOGIC_VECTOR (N-1 downto 0) ); end regnbit; architecture regn of regnbit is begin process(ck, rst) begin if rst = '1' then Q '0'); elsif ck'event and ck = '0' then if ce = '1' then Q <= D; end if; end process; end regn; Registrador generic define um parâmetro do módulo Uso: rx: regnbit generic map(8) port map(ck => ck, rst => rst, ce => wen, D => RD, Q => reg); Moraes & Calazans 2006

69 process (clock, reset) begin if reset = '1' then A <= 0;B <= 0; C <= 0; elsif clock'event and clock='1' then A <= entrada; B <= A; C <= B; end if; end process; 1) Desenhe o circuito acima utilizando flip-flops 2) A ordem das atribuições (A,B,C) é importante ? O que ocorreria se fosse uma linguagem de programação tipo C? Registrador de deslocamento Moraes & Calazans 2006

70 –Atribuição dentro/fora de process: process (clock, reset) begin if clock'event and clock='1' then A <= entrada; B <= A; C <= B; Y <= B and not (C);-- dentro do process end if; end process; X <= B and not (C); -- fora do process Qual a diferença de comportamento nas atribuições à X e a Y? –Conclusão: -sinais atribuídos em processos, com controle de clock, serão sintetizados com flip-flops. -Sinais fora de processos ou em processos sem variável de sincronismo (clock) serão sintetizados com lógica combinacional. Registrador Moraes & Calazans 2006

71 Contador entity contup is port ( clock, reset, Load, Enable: In std_logic; DATABUS : In Std_logic_Vector (5 downto 0); Upcount2 : Out Std_logic_Vector (5 downto 0)); end contup; architecture RTL of contup is Signal Upcount : std_logic_Vector (5 downto 0); begin Upcount2 <= Upcount; Upcounter : Process (clock, reset) begin if reset = '1' then Upcount <= "000000"; elsif clock'event and clock='1' then if ENABLE = '1' then if LOAD = '1' then Upcount <= DATABUS; else Upcount <= Upcount + 1; end if; end process Upcounter; end RTL; Moraes & Calazans 2006

72 ROM package ROM is -- definição de uma rom 12x4 constant largura : integer := 4; subtype palavra is std_logic_vector(1 to largura); subtype tamanho is integer range 0 to 11; type mem_rom is array (0 to 11) of palavra; constant ROM1 : mem_rom := "1100", "1100","0100","0000", "0110","0101","0111", "1100","0100","0000","0110","0101"); end ROM; Moraes & Calazans 2006

73 ROM use work.ROM.all; entity contador is port( clock, reset : in bit; waves : out palavra); end; architecture A of contador is signal step : tamanho := 0; begin waves <= ROM1(step);-- conteúdo da ROM na saída process begin wait until clock'event and clock='1'; if reset='1' then step <= 0;-- primeiro estado elsif step = tamanho'high then step <= tamanho'high;-- tranca ! else step <= step + 1;-- avança 1 passo end if; end process; end A; Moraes & Calazans 2006

74 Máquina de estados entity MOORE is port(entrada1, clock : in std_logic; saida1: out std_logic); end; architecture comportamental of MOORE is type STATES is (S0, S1, S2, S3); -- tipo enumerado signal EA, PE : STATES; begin controle: process(clock, reset) begin if reset=1 then EA <= S0; elsif clock'event and clock='1 then EA <= PE; end if; end process; combinacional: process(EA, entrada1) begin case EA is when S0 => saida1 <= '0'; if entrada1='0' then PE<=S0; else PE<=S2; end if; when S1 => saida1 <= '1'; if entrada1='0' then PE<=S0; else PE<=S2; end if; when S2 => saida1 <= '1'; if entrada1='0' then PE<=S2; else PE<=S3; end if; when S3 => saida1 <= '0'; if entrada1='0' then PE<=S3; else PE<=S1; end if; end case; end process; end comportamental;

75 Processador Cleopatra Material a seguir cedido pelos autores Calazans e Moraes.

76 Arquitetura CLEÓPATRA v3.0

77 Arquitetura CLEÓPATRA ce rw entity control is port (reset, ck, n, z, c, v : in std_logic; halt: out std_logic; ir : in regsize; uins : out microinstrucao ) end control; entity datapath is port( ck, reset : in std_logic; address, ir : out regsize; datamem : inout regsize; uins : in microinstrucao; n, z, c, v : out std_logic ); end datapath; DATAMEM ADDRESS MEMÓRIA dados e programa CPU ck reset halt

78 MICROINSTRUÇÃO => PALAVRA DE CONTROLE MAR MDR IR RS PC AC ULA BUS_B BUS_A 0 mux 1 sel escreve na memória lê da memória ADDRESS DATAMEM Codificação de escrita Codificação de leitura w r u lnz lcv CE RW CE RW type microinstrucao is record w,r,u: opcode; ce, rw, lnz, lcv : std_logic; end record; NZCV

79 Barramento de dados v3.0

80 FETCH 1/3 MAR (0) MDR (1) IR (2) RS (5) PC(3) AC (4) ULA 0 mux 1 sel escreve na memória lê da memória DATAMEM Codificação de escrita Codificação de leitura w r u lnz lcv CE RW CE RW NZCV MAR PC uins <= ( 0, 3, 7, '0', '0', '0', '0'); type microinstrucao is record w,r,u: opcode; ce, rw, lnz, lcv : std_logic; end record;

81 FETCH 2/3 MAR (0) MDR (1) IR (2) RS (5) PC(3) AC (4) ULA 0 mux 1 sel escreve na memória lê da memória DATAMEM Codificação de escrita Codificação de leitura w r u lnz lcv CE RW CE RW MDR PMEM(MAR); PC++ uins <= ( 1, 3, 1, '1', '1', '0', '0'); type microinstrucao is record w,r,u: opcode; ce, rw, lnz, lcv : std_logic; end record; NZCV

82 FETCH 3/3 MAR (0) MDR (1) IR (2) RS (5) PC(3) AC (4) ULA 0 mux 1 sel escreve na memória lê da memória DATAMEM Codificação de escrita Codificação de leitura w r u lnz lcv CE RW CE RW IR MDR uins <= ( 2, 1, 4, '0', '0', '0', '0'); type microinstrucao is record w,r,u: opcode; ce, rw, lnz, lcv : std_logic; end record; NZCV

83 BLOCO DE DADOS - COMPONENTES (7) MAR MDR IR RS PC AC ULA BUS_B BUS_A 0 mux 1 sel escreve na memória lê da memória ADDRESS DATAMEM Codificação de escrita Codificação de leitura w r u lnz lcv CE RW CE RW NZCV

84 BD - ACESSO À MEMÓRIA -- dados provenientes ou da memória ou da ULA sel1 <= uins.ce and uins.rw; outmux <= out_ula when sel1='0' else datamem; -- escrita para a memória sel2 <= uins.ce and (not uins.rw); datamem <= out_ula when sel2='1' else "ZZZZZZZZ"; 0 mux 1 sel escreve na memória lê da memória CE RW CE RW out_ula datamem

85 BD - REGISTRADORES ir <= reg_ir; -- instrução corrente, a ser utilizada no bloco de controle R1: reg8clear port map ( clock=>ck, reset=>reset, ce=>wmar, D=>out_ula, Q=>address); R2: reg8clear port map ( clock=>ck, reset=>reset, ce=>wmdr, D=>outmux, Q=>mdr); R3: reg8clear port map ( clock=>ck, reset=>reset, ce=>wir, D=>out_ula, Q=>reg_ir); R4: reg8clear port map ( clock=>ck, reset=>reset, ce=>wpc, D=>out_ula, Q=>pc); R5: reg8clear port map ( clock=>ck, reset=>reset, ce=>wac, D=>out_ula, Q=>ac); R6: reg8clear port map ( clock=>ck, reset=>reset, ce=>wrs, D=>out_ula, Q=>rs);

86 BD - ACESSO AOS BARRAMENTOS busB <= mdr when rmdr='1' else "ZZZZZZZZ"; busB <= reg_ir when rir='1' else "ZZZZZZZZ"; busA <= pc when rpc='1' else "ZZZZZZZZ"; busA <= ac when rac='1' else "ZZZZZZZZ"; busA <= rs when rrs='1' else "ZZZZZZZZ"; MDR IR RS PC AC ULA BUS_B BUS_A Uso de tri-states:

87 BD - CODIFICAÇÃO DE ESCRITA wmar <= '1' when uins.w=0 else '0'; wmdr <= '1' when uins.w=1 or uins.w=6 else '0'; wir <= '1when uins.w=2 else '0'; wpc <= '1' when uins.w=3 or uins.w=6 else '0'; wac <= '1' when uins.w=4 else '0'; wrs <= '1' when uins.w=5 else '0';

88 BD - CODIFICAÇÃO DE LEITURA rmdr <= '1' when uins.r =1 or uins.r=6 or uins.r=7 else '0'; rir <= '1' when uins.r =2 else '0'; rpc <= '1' when uins.r =3 or uins.r=7else '0'; rac <= '1' when uins.r =4 or uins.r=6else '0'; rrs <= '1' when uins.r=5 else '0';

89 BD - ULA um <= "00000001"; zero <= '0'; process(uins.u,busA,busB) begin case uins.u is when 0 => somaAB( busA, busB, zero, out_ula, cout); when 1 => somaAB( busA, um, zero, out_ula, cout); when 2 => out_ula <= not busA; when 4 => out_ula <= busB; when 5 => out_ula <= busA or busB; when 6 => out_ula <= busA and busB; when 7 => out_ula <= busA; when others => null; end case; end process;

90 BD - FLAGS DE ESTADO (falta v) Chamada de FUNÇÃO process(ck,reset,uins) begin if (reset='1') then c <= '0'; n <= '0'; z <= '0'; elsif ck'event and ck='0 then if uins.c='1' then c <= cout; end if; if uins.nz='1 then n <= out_ula(7); z <= is_zero(out_ula); end if; end process ;

91 BLOCO DE CONTROLE Função: gerar os sinais de controle para o bloco de dados, em função da instrução corrente e dos flags de estado. Estrutura básica do bloco de controle: process begin wait until ck'event and ck='1'; -- fetch -- uins <= mar_pc; wait until ck'event and ck='1'; uins <= mdr_MmarP; wait until ck'event and ck='1'; uins <= ir_mdr; wait until ck'event and ck='1'; case ir is -- seleção pelo opcode when xxxx => uins <= ac_ac; when others => null; end case; end process; MICROINS E ESPERA VOLTA Espera o clock SELECIONA

92 BLOCO DE CONTROLE Vantagens deste estilo de descrição: Simples de descrever o controle: fetch seguido de case para seleção da operação. Fácil de realizar a temporização: basta inserir após cada microinstrução uma espera por borda de clock. Atenção: após a última microinstrução do ciclo de instrução não vai wait. Razão: antes do fetch já tem inserido um wait. Esta temporização permite instruções com número diferente de ciclos para execução, como é o caso da arquitetura proposta.

93 BC - Exemplo de instrução (1) De acordo com a especificação LDA, ADD, OR, AND são praticamente iguais when ldaim | andim | orim | addim => uins <= mar_pc; wait until ck'event and ck='1'; uins <= mar_MmarP; wait until ck'event and ck='1'; sel_op (ir(7 downto 4), uins); Função para escolha do microcomando em função dos 4 bits mais significativos t0: MAR PC t1: MDR PMEM(MAR); PC++ t2: AC AC op MDR setar flags

94 (1) continuação Função para escolha do microcomando para LDA/ADD/OR/AND Inserir a função ou no package ou antes do begin flags procedure sel_op (signal ir: in std_logic_vector(3 downto 0); signal uins : out microinstrucao ) is begin case ir is when x"4" => uins <= (4, 1, 4, '0','0', 1','0'); -- ac <- mdr when x"5" => uins <= (4, 6, 0, '0','0', '1','1'); -- ac <- ac + mdr when x"6" => uins <= (4, 6, 5, '0','0', '1','0'); -- ac <- ac or mdr when x"7" => uins <= (4, 6, 6, '0','0', '1','0'); -- ac <- ac and mdr when others => null; end case; end sel_op;

95 BC - Exemplo de instrução (2) Micro código para os jumps (endereçamento direto) Trata-se todos os jumps juntos, no mesmo caso when jcdir | jndir | jzdir => uins <= mar_pc; wait until ck'event and ck='1'; uins <= mdr_MmarP; wait until ck'event and ck='1'; if (((jc and c)='1') or ((jn and n)='1') or ((jz and z)='1')) then uins <= pc_mdr; else uins <= nop; end if;

96 Crítica à implementação apresentada: BC - Exemplo de instrução (3) Micro código para o HALT : –implementa através de uma espera pelo reset when hlt => while reset='0' loop wait until ck'event and ck='1'; end loop; As seqüências mar_pc, mdr_MmarP, e mdr_Mmar são repetidas inúmeras vezes. Poder-se-ia ter escrito um código mais estruturado.

97 ENTIDADE CPU entity cleopatra is port( ck, reset: in std_logic; ce, rw, inicio : out std_logic; address: out regsize;datamem: inout regsize); end cleopatra; architecture cleopatra of cleopatra is component datapath is port(uins : in microinstrucao;ck, reset: in std_logic; ir, address : out regsize;datamem : inout regsize; n, z, c, v : out std_logic ); end component datapath; component control is port( ir : in regsize;n, z, c, v, ck, reset: in std_logic uins : out microinstrucao; ); end component control; signal uins : microinstrucao; signal n,z,c,v : std_logic; signal ir : regsize; begin

98 ENTIDADE CPU begin ce <= uins.ce; rw <= uins.rw; dp: datapath port map ( uins=>uins, ck=>ck, reset=>reset, ir=>ir, address=>address, datamem=>datamem, n=>n, z=>z, c=>c, v=>v); ctrl: control port map ( ir=>ir, n=>n, z=>z, c=>c, v=>v, ck=>ck, reset=>reset, uins=>uins); end cleopatra; SINAIS PARA A MEMÓRIA

99 TEST BENCH (1) Módulo responsável por gerar os vetores de teste para a simulação AÇÕES: 1 -- incluir a CPU no test_bench 2 -- gerar o clock 3 -- gerar o reset 4 -- ler da memória 5 -- escrever na memória, de maneira síncrona, como nos registradores 6 -- realizar a carga na memória quando acontece o reset

100 TEST BENCH (2) IMPLEMENTAÇÃO: architecture tb of tb is signal ck, reset, ce, rw, inicio: std_logic; signal address, data : regsize; file INFILE : TEXT open READ_MODE is "program.txt"; signal memoria : ram; signal ops, endereco : integer; begin BLÁ, BLÁ, BLÁ end tb Desnecessário inicializar Para carga do programa

101 TEST BENCH (3) 1 -- incluir a CPU no test_bench cpu : cleopatra port map(ck=>ck, reset=>reset, ce=>ce, rw=>rw, address=>address, datamem=>data); 2 -- gerar o clock process begin ck <= '1', '0' after 10ns; wait for 20ns; end process; 3 -- gerar o reset reset <= '1', '0' after 5ns ;

102 TEST BENCH (4) A MEMÓRIA É UM ARRAY, QUE É LIDO OU ESCRITO CONFORME OS SINAIS CE E RW. 4 -- ler da memória data <= memoria(CONV_INTEGER(address)) when ce='1' and rw='1' else "ZZZZZZZZ";

103 TEST BENCH (4 bis) 5 -- escrever na memória, de maneira síncrona, como nos registradores PROBLEMA para escrita - duas fontes de escrita: inicialização e Cleóptara. Solução: process(go, ce, rw, ck) begin if go'event and go='1' then if endereco>=0 and endereco <= 255 then memoria(endereco) <= conv_std_logic_vector(ops,8); end if; elsif ck'event and ck='0' and ce='1' and rw='0' then if CONV_INTEGER(address)>=0 and CONV_INTEGER(address) <= 255 then memoria(CONV_INTEGER(address)) <= data; end if end if; end process; escrita pelo test_bech escrita pela Cleópatra Importante: testar os limites da RAM

104 TEST BENCH (5) O PROGRAMA ARMAZENADO NA MEMÓRIA É CARREGADO QUANDO O RESET ESTÁ ATIVO 6 -- realizar a carga na memória quando acontece o reset process variable IN_LINE : LINE; -- pointer to string variable linha : string(1 to 5); begin wait until reset = '1'; while NOT( endfile(INFILE)) loop-- end file checking readline(INFILE,IN_LINE);-- read line of a file read(IN_LINE, linha); decodifica a linha e gera o sinal go end loop; end process; LAÇO DE LEITURA SUBIDA DO RESET

105 TEST BENCH (6) COMO CONVERTER A LINHA EM ENDEREÇO E DADO E GERAR GO : case linha(1) is when '0' => endereco <= 0; when '1' => endereco <= 1; when 'F' => endereco <=15; when others => null; end case; wait for 1 ps; case linha(2) is when '0' => endereco <= endereco*16 + 0; when '1' => endereco <= endereco*16 + 1; when 'F' => endereco <= endereco*16 + 15; when others => null; end case; -- linha (3) é espaço em branco case linha(4) is when '0' => ops <= 0; when '1' => ops <= 1; when 'F' => ops <=15; when others => null; end case; wait for 1 ps; case linha(5) is when '0' => ops <= ops*16 + 0; when '1' => ops <= ops*16 + 1; when 'F' => ops <= ops*16 + 15; when others => null; end case; wait for 1 ps; go <= '1'; wait for 1 ps; go <= 0'; Fazer uma função para converter um char em inteiro Pulso em go gera escrita na memória

106 SIMULAÇÃO (1) - PROGRAMA PROGRAMA (em código objeto) 00 40; endereço 00 LDA # 01 98; endereço 01 H98 02 54 ; endereço 02 ADD 03 10; endereço 03 H10 04 24 ; endereço 04 STA 05 11; endereço 05 H11 06 E0; endereço 06 HALT 10 77; endereço 10 H77 FUNÇÃO DO PROGRAMA: somar a constante H98 ao conteúdo do endereço H10 e depois gravar o resultado em H11

107 SIMULAÇ ÃO (2) Colocou 98 no acumulador no final da 1# instrução Soma da ac+mdr Soma inserida no MDR para ser escrito na memória Gerou carry Descida de Início indica nova instrução LDA # H98 ADD H10 STA H11 HALT 10 77 Endereço 11H Endereço 10H no MAR HALT WRITE

108 Referências http://www.seas.upenn.edu/~ese201/vhdl/vhdl_primer.html Fernando Gehm Moraes e Ney Calazans, PUCRS, notas de aula.


Carregar ppt "VHDL Very High Speed Integrated Circuit Hardware Description Language Prof. Eduardo Todt 2008."

Apresentações semelhantes


Anúncios Google