• Nenhum resultado encontrado

3.3

Perif´ericos

Similarmente `as instru¸c˜oes especializadas, projetistas podem integrar seus m´odulos de hardware a sistemas baseados no processador NIOS2. Entretanto, como o m´odulo fica ex- terno ao datapath do processador, temos maior grau de liberdade em sua implementa¸c˜ao. Dessa forma, por exemplo, podem-se ter m´odulos muito maiores sem prejudicar o de- sempenho do sistema, ou mesmo ter o m´odulo operando em freq¨uˆencias diferentes das utilizadas pelo NIOS2. No caso das instru¸c˜oes especializadas, isso era bastante dif´ıcil, uma vez que o m´odulo de hardware tinha necessariamente de operar na mesma freq¨uˆencia do processador. Outra vantagem ´e poder adotar chamadas n˜ao-bloqueantes aos m´odulos, permitindo o processador executar outras tarefas em paralelo ao processamento dos dados no perif´erico.

Nessa abordagem, os perif´ericos podem ser qualquer l´ogica que adote uma interface de comunica¸c˜ao com o barramento Avalon [21, 33]. O Avalon consiste de sinais de controle, e barramentos de dados e endere¸cos, sendo que os perif´ericos utilizam esse barramento para se comunicar com todos os outros componentes do sistema, como por exemplo, com o processador NIOS2. Essa situa¸c˜ao ´e mostrada na Figura 3.5.

Figura 3.5: Integra¸c˜ao do NIOS2 e Perif´ericos atrav´es do Barramento Avalon

Perif´ericos Avalon podem ser classificados como mestre (master) ou escravo (slave). Um perif´erico mestre ´e um perif´erico que pode iniciar transferˆencias no barramento Ava- lon. Um perif´erico mestre possui pelo menos uma porta mestre que se conecta com o barramento Avalon. Por´em, um perif´erico mestre pode tamb´em possuir portas escravas, as quais permitem o perif´erico receber transferˆencias iniciadas por outros mestres presen- tes no barramento. Um perif´erico escravo ´e um perif´erico que apenas aceita transferˆencias do barramento Avalon, e n˜ao pode inicia-las. Normalmente, perif´ericos escravos possuem apenas uma porta escrava, a qual se conecta com o barramento Avalon.

Nossos m´odulos foram implementados como perif´ericos escravos, sendo que n˜ao neces- sitamos que o perif´erico inicie transferˆencias pelo barramento. Uma interface em VHDL desses perif´ericos escravos, amplamente utilizada em nosso trabalho, ´e mostrada na Fi- gura 3.6.

entity <CP_NAME> is port(

clk : in std_logic; reset : in std_logic; chipselect : in std_logic;

address : in std_logic_vector(4 downto 0); write : in std_logic;

writedata : in std_logic_vector(31 downto 0); read : in std_logic;

readdata : out std_logic_vector(31 downto 0); waitrequest : out std_logic);

end <CP_NAME>;

Figura 3.6: Interface de um Perif´erico Escravo em VHDL

Os sinais chipselect e reset habilitam o in´ıcio de execu¸c˜ao da opera¸c˜ao, utilizando o sinal clk como clock do perif´erico. A entrada de dados ´e realizada por apenas um operando de 32 bits writedata quando habilitado por write. J´a a sa´ıda de dados ´e composta por outro canal de 32 bits readdata, e habilitado pelo sinal read. Quando necess´ario endere¸car registradores internos, ou enviar algum comando ao perif´erico utiliza- se o sinal address, tamb´em de 32 bits. Quando a opera¸c˜ao realizada pelo perif´erico toma mais de um ciclo para ser finalizada, o sinal waitrequest ´e assertado, e permanece nesse estado at´e o final da opera¸c˜ao. Nessa situa¸c˜ao, o processador fica em um estado de espera, impossibilitado de executar outras opera¸c˜oes. Dessa maneira, se o projetista deseja executar opera¸c˜oes em paralelo no NIOS2, faz-se necess´ario adotar alguma estrat´egia de bufferiza¸c˜ao de argumentos e resultados, liberando o processador da espera.

Em nossas implementa¸c˜oes adotamos chamadas bloqueantes, dado que n˜ao necessita- mos dos servi¸cos do processador em paralelo ao processamento do perif´erico. Entretanto, pretendemos melhorar os m´odulos no futuro de forma a possibilitar o processador es- crever/ler dados no/do perif´erico ao mesmo tempo em que ele realiza o processamento de uma opera¸c˜ao. Dessa maneira, um pipeline de escrita-execu¸c˜ao-leitura seria formado, resultando em maior desempenho do sistema em chamadas sucessivas da mesma opera¸c˜ao. Toda inser¸c˜ao de perif´ericos do NIOS2 ´e realizada pela ferramenta SOPC Builder da Altera. Essa ferramenta automaticamente gera um novo sistema utilizando o m´odulo de hardware como perif´erico do processador NIOS2. A partir da descri¸c˜ao do m´odulo em alguma linguagem de descri¸c˜ao de hardware, como VHDL ou Verilog, a ferramenta SOPC Builder automaticamente gera a l´ogica de interconex˜ao, incluindo decodifica¸c˜ao de endere¸cos, multiplexa¸c˜ao do datapath, gera¸c˜ao de wait-states, controle de interrup¸c˜oes, e corre¸c˜ao de largura de dados dos barramentos.

Nesse trabalho n˜ao utilizamos interrup¸c˜oes. Isso para poder analisar o tempo gasto somente em uma opera¸c˜ao simples. O uso de interrup¸c˜oes em um sistema real seria

3.3. Perif´ericos 27

interessante, pois o processador poderia se dedicar a outras tarefas enquanto a opera¸c˜ao ´

e executada. Como, nesse trabalho, o processador est´a dedicado somente a execu¸c˜ao de uma opera¸c˜ao espec´ıfica, acreditamos que uma abordagem simplificada seria suficiente para a an´alise de desempenho. Da mesma maneira, pode-se pensar em acelerar o sistema com o uso de DMA. Entretanto isso demandaria um pouco mais de l´ogica no m´odulo de hardware, pois esse teria de se tornar um mestre do barramento Avalon, implicando em maior ´area de implementa¸c˜ao. Como conseq¨uˆencia, poder´ıamos ter uma perda de desempenho do m´odulo. Novamente, como estamos preocupados apenas com o n´ucleo de execu¸c˜ao de cada opera¸c˜ao, uma abordagem simplificada ´e suficiente para nossas an´alises. Para interfacear com o m´odulo basta incluir uma biblioteca (io.h) que cont´em as macros de chamadas ao perif´erico. A Figura 3.7 exemplifica como ´e feita a chamada a um perif´erico utilizando a linguagem C. Diferentemente de como ´e feito nas chamadas de instru¸c˜oes especializadas, uma chamada de escrita a um perif´erico envia apenas uma palavra e um identificador. No caso da primeira chamada de escrita (WR) da Figura 3.7, tem-se o envio da palavraa[0] e do identificador 0 para o m´odulo de hardware. Somente depois das chamadas de escrita ´e que se pode obter algum resultado vindo do perif´erico atrav´es de chamadas de leitura (RD).

#include <io.h> void main() {

u32 a[6], b[6], c[6]; ...

// Chamadas de escrita no perif´erico

// IOWR(CP_BASE_ADDRESS, offset, writedata); IOWR(<CP_NAME>_BASE, 0, a[0]); ... IOWR(<CP_NAME>_BASE, 5, a[5]); IOWR(<CP_NAME>_BASE, 6, b[0]); ... IOWR(<CP_NAME>_BASE, 11, b[5]); // Chamadas de leitura do perif´erico // readdata = (CP_BASE_ADDRESS, offset); c[0] = IORD(<CP_NAME>_BASE, 0);

...

c[5] = IORD(<CP_NAME>_BASE, 5); }

Documentos relacionados