• Nenhum resultado encontrado

SIMULAÇÃO DA REDE HERMES

N/A
N/A
Protected

Academic year: 2021

Share "SIMULAÇÃO DA REDE HERMES"

Copied!
13
0
0

Texto

(1)

SIMULAÇÃO DA REDE HERMES

FERNANDO GEHM MORAES

Revisão: 26/abril/2018

O objetivo do presente tutorial é compreender a sinalização da interface da rede, e dominar o

processo de integração de módulos de hardware à mesma.

A rede HERMES, e seu ambiente de síntese, denominado ATLAS, está disponível para download no link:

https://corfu.pucrs.br/redmine/projects/atlas/wiki

.

Obtenha a distribuição do ambiente digitando:

wget

http://www.inf.pucrs.br/moraes/docs/atlas_distrib.tar

Configuração do ambiente de trabalho – arquivo atlas.sh

ATLAS=$HOME/atlas_distrib

export ATLAS_HOME=$ATLAS

export PATH=${ATLAS}:/soft64/mentor/ferramentas/modelsim/10.3c/modeltech/linux_x86_64:${PATH}

Inseri na raiz da sua conta um arquivo denominado .atlas:

{BrowserFile}/usr/bin/Firefox

Execute "source atlas.sh"

Se der problema para abrir, execute o linuxcompile

Atividade 1 – geração da rede para a simulação.

Executar a ferramenta atlas e criar um novo projeto, conforme Figura 1.

(2)

Selecionar a opção “NoC Generation”, definindo-se os parâmetros da rede conforme a Figura 2: rede sem

canais virtuais, controle de fluxo credit based, 3x3, flit de 16 bits, profundidade do buffer igual a 8.

Figura 2 - Interface gráfica para geração da NoC.

• Clicar no botão “Generate”, criando-se a rede 3x3. O botão “generate” cria a estrutura de diretórios

apresentada na Figura 3.

Figura 3 – Estrutura de diretórios gerada pela ferramenta Atlas, opção geração da NoC (MAIA).

Sinais de interface da rede HERMES

1. Como não iremos trabalhar com injeção de dados a partir de SystemC, remover do arquivo

topNoC.vhd

(no

diretório <work>\<nome do projeto>) a entidade inputmodule (na prática apagar da linha 96 a 136).

2. A figura 4 mostra:

a. Índice dos roteadores;

(3)

c. Sinais entre a interface de rede e o roteador. Notar que a transmissão é síncrona. Quando há dados para

transmitir, o sinal rx sobe, e dados são colocados em data_in. Se o roteador não está apto a receber

dados, o sinal credit_o vai para zero.

Figura 4 – Sinais de interface dos roteadores e índices das portas.

Atividade 2 – Escrita do processo responsável por injetar dados na rede

1. A simulação que iremos fazer inicialmente injetará dados no roteador 00, com destino para o roteador 22. Nesta

condição, devemos desabilitar a transmissão de dados por parte de todos os outros roteadores, exceto para o

roteador 00. Para isto, acrescente no final do arquivo

topNoC.vhd

para todos os roteadores, exceto o 00, as

seguintes linhas:

clock_rx(

endereço

) <= '0';

rx(

endereço

) <= '0';

Onde

endereço

assume os valores N0100, N0200, N0001, N0101, N0201, N0002, N0102, N0202

(inserção de 16 linhas de VHDL).

Cada par clock_rx/rx em zero impede que dados entrem nos roteadores, pois não há atividade do clock de

recepção do roteador, e o sinal rx nunca sinaliza que novos dados estão chegando.

2. Definição dos sinais necessários para a injeção de dados (inserir entre architecuture e begin):

signal address1, data1: std_logic_vector(15 downto 0);

signal ce1: std_logic;

Os sinais address1, data1 e ce1 correspondem a sinais com funcionalidade de uma interface padrão de

processador, ou seja, quando o ce estiver ativo, significa que há dado em data para o endereço address.

type packet is array (0 to 16) of std_logic_vector(15 downto 0);

Esta linha define um pacote de 17 flits (0 a 16), sendo cada flit de largura de 16 bits.

constant pck1 : packet :=

( x"0022", x"000F", x"1001", x"2002", x"3003", x"4004", x"5005",

x"6006", x"7007", x"8008", x"9009", x"A00A",

x"B00B", x"C00C", x"D00D", x"E00E", x"F00F"

);

ROUTER 02 ROUTER12 ROUTER22 ROUTER 01 ROUTER11 ROUTER21 ROUTER 00 ROUTER10 ROUTER20 Network interface

data_in

rx

credit_o

ad

dr

es

s

da

ta

ce

cr

ed

it_

o

ROUTER

2

3

1

0

NI

Processor

4

Port indexes:

There is another signal in the interface,

named clock_rx which can be the same

of the clock router

(4)

Esta linha constrói o pacote o pacote que iremos transmitir. O primeiro flit corresponde ao endereço destino

do pacote (0022), tamanho do pacote (000F), e na seqüência os 15 flits do payload.

3. Escrita da interface de rede, a qual faz a ligação dos sinais de um IP (por exemplo, um processador) como

address1, data1 e ce1 aos sinais da NoC (credit_o, rx, data_in). Um exemplo de interface de rede, muito

simples, é dado abaixo:

clock_rx(N0000) <= clock(N0000); -- clock to inject data - the same of the router

process(reset, clock(N0000))

begin

if reset='1' then

rx(N0000) <= '0';

elsif clock(N0000)'event and clock(N0000)='1' then

if ce1='1' and address1=x"FFFF" then

rx(N0000) <= '1';

data_in(N0000) <= data1;

elsif credit_o(N0000)='1' then -- important: flow control

rx(N0000) <= '0';

end if;

end if;

end process;

O princípio de operação deste código VHDL é simples. Inicialmente atribui-se ao clock de recepção o

mesmo clock do roteador. Depois, um processo síncrono é responsável por gerenciar a geração do sinal rx.

Sempre que o processador ativar o CE e escrever algum dado no endereço 0xFFFF, este dado é repassado à

NoC, ativando-se o sinal rx. Notar que se não há crédito, o sinal rx permanece com valor ‘0’.

Acrescente este código após as linhas que desabilitaram injeção de tráfego para os demais roteadores.

4. O passo seguinte corresponde a escrever o comportamento de um processador, o qual deve injetar o pacote

definido no primeiro passo acima. Se fôssemos escrever um código C para a escrita de um pacote no ponteiro

data, teríamos:

do

{ while( credit_o==0 ); // waits until the availability of credit

store_word( data, address_noc);

}

A NoC, como já vimos no segundo passo, está mapeada no endereço 0xFFFF. Um exemplo de código

VHDL que simula o comportamento desta rotina C é apresentado abaixo. Insira este código após a

interface de rede.

address1 <= x"FFFF";

-- address generated by the processor

process

variable i : integer:= 0;

begin

ce1 <= '0';

wait for 400 ns;

-- time between packets

i := 0;

while i < 17 loop

if credit_o(N0000)='1' then

-- important: flow control

data1 <= pck1(i);

-- simulate a write( pck(i), address_noc)

ce1 <= '1';

wait for 20 ns;

ce1 <= '0';

wait for 20 ns;

i := i + 1;

else

wait for 20 ns;

end if;

(5)

end loop;

end process;

Atividade 3 - Simulação

1. Ir para o diretório de trabalho. Exemplo: cd {D:\noc_lab\noc1}

2. Modificar o arquivo simulate.do comentando a linha 6 (#sccom -g SC_NoC/SC_InputModule.cpp),

suprimindo as linhas 28 a 30 – elas inicializam a simulação e depois fecham o ModelSim.

3. Execute o script: do simulate.do. Pode demorar um pouco, pois há algumas rotinas SystemC compilada.

4. Inserir os sinais de interface, ou insira os comando abaixo no arquivo wave.do e execute no ModelSim do

wave.do. Estaremos visualizando as interfaces sinalizadas com círculos vermelhos na figura.

add wave -divider {FONTE DOS DADOS}

add wave -format Logic /topnoc/ce1

add wave -format Literal -radix hexadecimal /topnoc/data1 add wave -divider {roteador 00 PORTA LOCAL} add wave -format Logic /topnoc/noc/router0000/clock add wave -format Logic /topnoc/noc/router0000/rx(4) add wave -format Logic /topnoc/noc/router0000/credit_o(4)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0000/data_in(4) add wave -divider {roteador 00 PORTA LESTE}

add wave -format Logic /topnoc/noc/router0000/tx(0) add wave -format Logic /topnoc/noc/router0000/credit_i(0)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0000/data_out(0) add wave -divider {roteador 10 PORTA LESTE}

add wave -format Logic /topnoc/noc/router0100/tx(0) add wave -format Logic /topnoc/noc/router0100/credit_i(0)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0100/data_out(0) add wave -divider {roteador 20 PORTA NORTE}

add wave -format Logic /topnoc/noc/router0200/tx(2) add wave -format Logic /topnoc/noc/router0200/credit_i(2)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0200/data_out(2) add wave -divider {roteador 21 PORTA NORTE}

add wave -format Logic /topnoc/noc/router0201/tx(2) add wave -format Logic /topnoc/noc/router0201/credit_i(2)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0201/data_out(2) add wave -divider {roteador 22 PORTA LOCAL}

add wave -format Logic /topnoc/noc/router0202/tx(4) add wave -format Logic /topnoc/noc/router0202/credit_i(4)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0202/data_out(4)

5. Execute a simulação por 2 us: run 2 us. Deve-se obter a janela abaixo:

ROUTER 02 ROUTER12 ROUTER22 ROUTER 01 ROUTER11 ROUTER21 ROUTER 00 2 ROUTER10 3 ROUTER20 4 5 1

Caminho determinado pelo algoritmo de roteamento XY

(6)

Figura 5– Simulação com transferência de um pacote do roteador 00 para o roteador 22.

Notar na simulação:

• O pacote começa a ser inserido na porta local do roteador 00 no tempo 400 ns. O pacote é

arbitrado e roteado em 5 ciclos de clock, estando disponível no tempo 500ns na porta leste do

roteador 00 (intervalo 1 da figura 4) .

• Os intervalos 2/3/4/5 mostram o caminhamento do pacote ao longo do caminho.

• A latência total do pacote é de 25 ciclos de clock (5 ciclos por hop) mais o tamanho do pacote, 17

ciclos de clock. Assim, em nanosegundos, a latência total é de (25+17)*20 = 840 ns.

• Somando-se o tempo 400 ns com 840 ns, tem-se o tempo de recepção do último flit, que é 1240

ns.

Observar no diretório de trabalho que vários arquivos textos foram gerados. Dentre estes, temos o

out8.txt, que corresponde à recepção dos dados no roteador 8 (22 no nosso caso). Simulando 10 us

obtemos a recepção de 9 pacotes:

0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 003F 1074024453 -1609912309 63 -1074024 390 35

0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 0075 1074024453 -1609912309 117 -107402 4336 37

0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 00AB 1074024453 -1609912309 171 -107402 4282 39

0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 00E1 1074024453 -1609912309 225 -107402 4228 40 0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 0117 1074024453 -1609912309 279 -107402 4174 42 0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 014D 1074024453 -1609912309 333 -107402 4120 44 0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 0183 1074024453 -1609912309 387 -107402 4066 45 0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 01B9 1074024453 -1609912309 441 -107402 4012 47

1

2

3

4

5

(7)

0022 000F 1001 2002 3003 4004 5005 6006 7007 8008 9009 A00A B00B C00C D00D E00E F00F 0000 0000 0000 01EF 1074024453 -1609912309 495 -107402 3958 49

Os valores “estranhos” ao final do pacote deve-se ao fato que não utilizamos SystemC para geração de

dados. São campos para cálculo de latência.

Pode-se observar também os dados passando em cada porta dos roteadores nos arquivos texto.

Atividade 4 – Simulação com a Interface Gráfica

• Execute novamente a ferramenta ATLAS, abrindo o projeto original. Gere novamente a rede para

obter os arquivos originais. Se for pedido um navegador, selecione /usr/bin/firefox

Lembre

: fazer backup do topnoc.vhd!

• Após a geração da rede, selecione Traffic Generation. Crie um cenário de simulação:

• Gere o tráfego a uma taxa de 160 Mbps para o destino 22. O cálculo é simples: o canal tem largura

de 16 bits. Logo, a 50MHz a banda do canal é de 800 Mbps. 20% corresponde a 160 Mbps. Ao

gerar-se o tráfego é aberta uma tela de confirmação

• Simular por 10 us:

(8)

Notar que foram transmitidos 10 pacotes, com taxa média de 20%, com a vazão igual a taxa de

injeção, pois não houveram colisões de pacotes. A latência média foi de 41 ciclos.

Atividade 5 – Exercício

1. Observe que a inserção dos flits ocorre a cada dois ciclos de clock. Durante um ciclo de clock o ce

está ativo, para sinalizar dado, e no outro ciclo de clock está em zero. Note entretanto, que na

recepção dos dados (data_out) os mesmo começam a ficar agrupados, resultando no destino a

recepção de um flit por ciclo de clock. O que explicaria este comportamento?

2. Modifique a geração de tráfego para duas origens enviando para o mesmo destino, 00à12 e 20à12.

Apresente a forma de onda resultante, analisando os resultados obtidos.

• Utilizar os seguintes pacotes:

constant pck1 : packet := ( x"0012", x"000F", x"1001", x"2002", x"3003", x"4004", x"5005", x"6006", x"7007", x"8008", x"9009", x"A00A", x"B00B", x"C00C", x"D00D", x"E00E", x"F00F" ); constant pck2 : packet := ( x"0012", x"000F", x"FFFF", x"EEEE", x"DDDD", x"CCCC", x"BBBB", x"AAAA", x"9999", x"8888", x"7777", x"6666", x"5555", x"4444", x"3333", x"2222", x"1111" );

• Sugestão para wave.do inicial:

add wave -divider {FONTE DOS DADOS 00} add wave -format Logic /topnoc/ce1

add wave -format Literal -radix hexadecimal /topnoc/data1 add wave -divider {FONTE DOS DADOS 20}

add wave -format Logic /topnoc/ce2

add wave -format Literal -radix hexadecimal /topnoc/data2 add wave -divider {roteador 12 PORTA LOCAL}

add wave -format Logic /topnoc/noc/router0102/tx(4) add wave -format Logic /topnoc/noc/router0102/credit_i(4)

add wave -format Literal -radix hexadecimal /topnoc/noc/router0102/data_out(4)

• Modifique o intervalo entre pacotes para 200 ns (wait for 200 ns;).

• Após a simulação, digitar o comando quit –sim, pode-se abrir o arquivo out7.txt o qual contém o

relatório dos pacotes recebidos. Há valores inseridos no final de cada linha, que seriam utilizados

pelas rotinas SystemC, desconsidere-os. Considerar apenas a parte relativa ao pacote. Os pacotes

foram corretamente recebidos?

(9)

********************************************************************************** noc.vhd --> instancia os roteadores e o gerador de relatórios

********************************************************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use work.HermesPackage.all; entity NOC is port( clock : in regNrot; reset : in std_logic; clock_rxLocal : in regNrot; rxLocal : in regNrot; data_inLocal : in arrayNrot_regflit; credit_oLocal : out regNrot; clock_txLocal : out regNrot; txLocal : out regNrot;

data_outLocal : out arrayNrot_regflit; credit_iLocal : in regNrot);

end NOC;

architecture NOC of NOC is

signal clock_rxN0000, clock_rxN0100, clock_rxN0200, clock_rxN0300 : regNport; ....

signal credit_iN0003, credit_iN0103, credit_iN0203, credit_iN0303 : regNport; begin

Router0000 : Entity work.RouterBL generic map( address => ADDRESSN0000 ) port map( clock => clock(N0000), reset => reset, clock_rx => clock_rxN0000, rx => rxN0000, data_in => data_inN0000, credit_o => credit_oN0000, clock_tx => clock_txN0000, tx => txN0000, data_out => data_outN0000, credit_i => credit_iN0000); Router0100 : Entity work.RouterBC generic map( address => ADDRESSN0100 ) port map( clock => clock(N0100), reset => reset, clock_rx => clock_rxN0100, rx => rxN0100, data_in => data_inN0100, credit_o => credit_oN0100, clock_tx => clock_txN0100, tx => txN0100, data_out => data_outN0100, credit_i => credit_iN0100); ... fios de ligação -- ROUTER 0000 -- EAST port clock_rxN0000(0)<=clock_txN0100(1); rxN0000(1)<='0'; ....

-- the component below, router_output, must be commented to simulate without SystemC router_output: Entity work.outmodulerouter

port map( clock => clock(N0000), reset => reset, ... credit_ir15p3 => credit_iN0303(SOUTH)); end NOC; ********************************************************************************** routercc --> roteador central

**********************************************************************************

entity RouterCC is

generic( address: regmetadeflit); port( clock: in std_logic; reset: in std_logic; clock_rx: in regNport; rx: in regNport; data_in: in arrayNport_regflit; credit_o: out regNport; clock_tx: out regNport; tx: out regNport;

data_out: out arrayNport_regflit; credit_i: in regNport);

end RouterCC;

architecture RouterCC of RouterCC is

signal h, ack_h, data_av, sender, data_ack: regNport := (others=>'0'); signal data: arrayNport_regflit := (others=>(others=>'0'));

signal mux_in, mux_out: arrayNport_reg3 := (others=>(others=>'0')); signal free: regNport := (others=>'0');

begin

FEast : Entity work.Hermes_buffer port map(... );

FWest : Entity work.Hermes_buffer port map(... );

FNorth : Entity work.Hermes_buffer port map(... );

FSouth : Entity work.Hermes_buffer port map(... );

FLocal : Entity work.Hermes_buffer port map(... );

SwitchControl : Entity work.SwitchControl(AlgorithmXY) port map(... );

CrossBar : Entity work.Hermes_crossbar port map(... );

(10)

********************************************************************************** buffer.vhd ********************************************************************************** entity Hermes_buffer is port( clock: in std_logic; reset: in std_logic; clock_rx: in std_logic; rx: in std_logic; data_in: in regflit; credit_o: out std_logic; h: out std_logic; ack_h: in std_logic; data_av: out std_logic; data: out regflit; data_ack: in std_logic; sender: out std_logic); end Hermes_buffer;

architecture Hermes_buffer of Hermes_buffer is

type fifo_out is (S_INIT, S_HEADER, S_SENDHEADER, S_PAYLOAD, S_END); signal EA : fifo_out;

signal buf: buff := (others=>(others=>'0')); signal read_pointer,write_pointer: pointer ; signal counter_flit: regflit ;

signal data_available : std_logic; begin

--- -- IF:

-- write_pointer /= read_pointer : FIFO WITH SPACE TO WRITE -- read_pointer + 1 == write_pointer : FIFO EMPTY

-- write_pointer == read_pointer : FIFO FULL

--- --- -- PROCESS TO WRITE INTO THE FIFO

--- process(reset, clock)

begin

if reset='1' then

write_pointer <= (others => '0'); elsif clock'event and clock='1' then

-- if receiving data and fifo isn't empty, record data on fifo and increase write pointer if rx = '1' and write_pointer /= read_pointer then

buf(CONV_INTEGER(write_pointer)) <= data_in; write_pointer <= write_pointer + 1; end if; end if; end process;

-- If fifo isn't empty, credit is high. Else, low

credit_o <= '1' when write_pointer /= read_pointer else '0';

--- -- PROCESS TO READ THE FIFO

--- -- Available the data to transmission (asynchronous read)

data <= buf(CONV_INTEGER(read_pointer)); process(reset, clock) begin if reset='1' then h <= '0'; data_available <= '0'; sender <= '0';

-- Initialize the read pointer with one position before the write pointer read_pointer <= (others=>'1');

EA <= S_INIT;

elsif clock'event and clock='1' then case EA is

when S_INIT =>

counter_flit <= (others=>'0'); h<='0';

data_available <= '0'; -- If fifo isn`t empty

if (read_pointer + 1 /= write_pointer) then -- Routing request to Switch Control h<='1';

-- consume de 1st flit - target address read_pointer <= read_pointer + 1; EA <= S_HEADER;

end if;

when S_HEADER =>

-- When the Switch Control confirm the routing if ack_h='1' then

h <= '0'; -- Disable the routing request

sender <= '1'; -- Enable wrapper signal to packet transmission data_available <= '1';

EA <= S_SENDHEADER ; end if;

when S_SENDHEADER =>

-- If the data available is read or was read if data_ack = '1' or data_available = '0' then -- If fifo isn`t empty

if (read_pointer + 1 /= write_pointer) then data_available <= '1';

read_pointer <= read_pointer + 1; -- consumes de 2 flit (payload size) EA <= S_PAYLOAD;

-- If fifo is empty (protection clause) else

data_available <= '0'; end if;

end if;

when S_PAYLOAD =>

-- If the data available is read or was read if data_ack = '1' or data_available = '0' then -- If fifo isn`t empty or is tail

if (read_pointer + 1 /= write_pointer) or counter_flit = x"1" then -- If the second flit, memorize the packet size

if counter_flit = x"0" then

counter_flit <= buf(CONV_INTEGER(read_pointer)); elsif counter_flit /= x"1" then

counter_flit <= counter_flit - 1; end if;

-- If the tail flit

if counter_flit = x"1" then -- If tail is send if data_ack = '1' then data_available <= '0'; sender <= '0'; EA <= S_INIT; else EA <= S_END;

(11)

else

data_available <= '1';

read_pointer <= read_pointer + 1; end if;

-- If fifo is empty (protection clause) else

data_available <= '0'; end if;

end if; when S_END => -- When tail is send if data_ack = '1' then data_available <= '0'; sender <= '0'; EA <= S_INIT; end if; end case; end if; end process; data_av <= data_available; end Hermes_buffer; ********************************************************************************** Hermes_switchcontrol.vhd ********************************************************************************** library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_unsigned.all; use work.HermesPackage.all; entity SwitchControl is port( clock : in std_logic; reset : in std_logic; h : in regNport; ack_h : out regNport; address : in regmetadeflit; data : in arrayNport_regflit; sender : in regNport; free : out regNport;

mux_in : out arrayNport_reg3; mux_out : out arrayNport_reg3); end SwitchControl;

architecture AlgorithmXY of SwitchControl is type state is (S0,S1,S2,S3,S4,S5,S6,S7); signal ES, PES: state;

-- sinais do arbitro signal ask: std_logic := '0';

signal sel,prox: integer range 0 to (NPORT-1) := 0; signal incoming: reg3 := (others=> '0');

signal header : regflit := (others=> '0'); -- sinais do controle

signal sender_ant: regNport := (others=> '0'); begin

ask <= '1' when h(LOCAL)='1' or h(EAST)='1' or h(WEST)='1' or h(NORTH)='1' or h(SOUTH)='1' else '0'; incoming <= CONV_VECTOR(sel); header <= data(CONV_INTEGER(incoming)); process(sel,h) begin case sel is when LOCAL=>

if h(EAST)='1' then prox<=EAST; elsif h(WEST)='1' then prox<=WEST; elsif h(NORTH)='1' then prox<=NORTH; elsif h(SOUTH)='1' then prox<=SOUTH; else prox<=LOCAL; end if;

when EAST=>

if h(WEST)='1' then prox<=WEST; elsif h(NORTH)='1' then prox<=NORTH; elsif h(SOUTH)='1' then prox<=SOUTH; elsif h(LOCAL)='1' then prox<=LOCAL; else prox<=EAST; end if;

when WEST=>

if h(NORTH)='1' then prox<=NORTH; elsif h(SOUTH)='1' then prox<=SOUTH; elsif h(LOCAL)='1' then prox<=LOCAL; elsif h(EAST)='1' then prox<=EAST; else prox<=WEST; end if;

when NORTH=>

if h(SOUTH)='1' then prox<=SOUTH; elsif h(LOCAL)='1' then prox<=LOCAL; elsif h(EAST)='1' then prox<=EAST; elsif h(WEST)='1' then prox<=WEST; else prox<=NORTH; end if;

when SOUTH=>

if h(LOCAL)='1' then prox<=LOCAL; elsif h(EAST)='1' then prox<=EAST; elsif h(WEST)='1' then prox<=WEST; elsif h(NORTH)='1' then prox<=NORTH; else prox<=SOUTH; end if;

end case; end process;

lx <= address((METADEFLIT - 1) downto QUARTOFLIT); ly <= address((QUARTOFLIT - 1) downto 0);

tx <= header((METADEFLIT - 1) downto QUARTOFLIT); ty <= header((QUARTOFLIT - 1) downto 0);

dirx <= WEST when lx > tx else EAST; diry <= NORTH when ly < ty else SOUTH; process(reset,clock)

begin

(12)

process(ES,ask,h,lx,ly,tx,ty,auxfree,dirx,diry) begin

case ES is

when S0 => PES <= S1;

when S1 => if ask='1' then PES <= S2; else PES <= S1; end if; when S2 => PES <= S3;

when S3 => if lx = tx and ly = ty and auxfree(LOCAL)='1' then PES<=S4; elsif lx /= tx and auxfree(dirx)='1' then PES<=S5;

elsif lx = tx and ly /= ty and auxfree(diry)='1' then PES<=S6; else PES<=S1; end if;

when S4 => PES<=S7; when S5 => PES<=S7; when S6 => PES<=S7; when S7 => PES<=S1; end case; end process; process (clock) begin

if clock'event and clock='1' then case ES is -- Zera vari�veis when S0 => sel <= 0; ack_h <= (others => '0'); auxfree <= (others=> '1'); sender_ant <= (others=> '0'); mux_out <= (others=>(others=>'0')); source <= (others=>(others=>'0')); -- Chegou um header when S1=> ack_h <= (others => '0');

-- Seleciona quem tera direito a requisitar roteamento when S2=>

sel <= prox;

-- Estabelece a conex�o com a porta LOCAL when S4 =>

source(CONV_INTEGER(incoming)) <= CONV_VECTOR(LOCAL); mux_out(LOCAL) <= incoming;

auxfree(LOCAL) <= '0'; ack_h(sel)<='1';

-- Estabelece a conex�o com a porta EAST ou WEST when S5 =>

source(CONV_INTEGER(incoming)) <= CONV_VECTOR(dirx); mux_out(dirx) <= incoming;

auxfree(dirx) <= '0'; ack_h(sel)<='1';

-- Estabelece a conex�o com a porta NORTH ou SOUTH when S6 =>

source(CONV_INTEGER(incoming)) <= CONV_VECTOR(diry); mux_out(diry) <= incoming;

auxfree(diry) <= '0'; ack_h(sel)<='1';

when others => ack_h(sel)<='0'; end case;

sender_ant(LOCAL) <= sender(LOCAL); sender_ant(EAST) <= sender(EAST); sender_ant(WEST) <= sender(WEST);

if sender(LOCAL)='0' and sender_ant(LOCAL)='1' then auxfree(CONV_INTEGER(source(LOCAL))) <='1'; end if; if sender(EAST) ='0' and sender_ant(EAST)='1' then auxfree(CONV_INTEGER(source(EAST))) <='1'; end if;

if sender(WEST) ='0' and sender_ant(WEST)='1' then auxfree(CONV_INTEGER(source(WEST))) <='1'; end if;

if sender(NORTH)='0' and sender_ant(NORTH)='1' then auxfree(CONV_INTEGER(source(NORTH))) <='1'; end if;

if sender(SOUTH)='0' and sender_ant(SOUTH)='1' then auxfree(CONV_INTEGER(source(SOUTH))) <='1'; end if;

end if; end process; mux_in <= source; free <= auxfree; end AlgorithmXY; ********************************************************************************** crossbar.vhd ********************************************************************************** ibrary IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use work.HermesPackage.all; entity Hermes_crossbar is port( data_av: in regNport; data_in: in arrayNport_regflit; data_ack: out regNport; sender: in regNport; free: in regNport; tab_in: in arrayNport_reg3; tab_out: in arrayNport_reg3; tx: out regNport;

data_out: out arrayNport_regflit; credit_i: in regNport);

end Hermes_crossbar;

architecture Hermes_crossbar of Hermes_crossbar is begin

--- -- PORTA LOCAL

---

tx(LOCAL) <= data_av(EAST) when tab_out(LOCAL)="000" and free(LOCAL)='0' else data_av(WEST) when tab_out(LOCAL)="001" and free(LOCAL)='0' else data_av(NORTH) when tab_out(LOCAL)="010" and free(LOCAL)='0' else data_av(SOUTH) when tab_out(LOCAL)="011" and free(LOCAL)='0' else '0';

data_out(LOCAL) <= data_in(EAST) when tab_out(LOCAL)="000" and free(LOCAL)='0' else data_in(WEST) when tab_out(LOCAL)="001" and free(LOCAL)='0' else

data_in(NORTH) when tab_out(LOCAL)="010" and free(LOCAL)='0' else data_in(SOUTH) when tab_out(LOCAL)="011" and free(LOCAL)='0' else

(13)

data_ack(LOCAL) <= credit_i(EAST) when tab_in(LOCAL)="000" and data_av(LOCAL)='1' else credit_i(WEST) when tab_in(LOCAL)="001" and data_av(LOCAL)='1' else

credit_i(NORTH) when tab_in(LOCAL)="010" and data_av(LOCAL)='1' else credit_i(SOUTH) when tab_in(LOCAL)="011" and data_av(LOCAL)='1' else '0';

--- -- PORTA EAST

---

tx(EAST) <= data_av(WEST) when tab_out(EAST)="001" and free(EAST)='0' else data_av(NORTH) when tab_out(EAST)="010" and free(EAST)='0' else data_av(SOUTH) when tab_out(EAST)="011" and free(EAST)='0' else data_av(LOCAL) when tab_out(EAST)="100" and free(EAST)='0' else '0';

data_out(EAST) <= data_in(WEST) when tab_out(EAST)="001" and free(EAST)='0' else data_in(NORTH) when tab_out(EAST)="010" and free(EAST)='0' else

data_in(SOUTH) when tab_out(EAST)="011" and free(EAST)='0' else data_in(LOCAL) when tab_out(EAST)="100" and free(EAST)='0' else (others=>'0');

data_ack(EAST) <= credit_i(WEST) when tab_in(EAST)="001" and data_av(EAST)='1' else credit_i(NORTH) when tab_in(EAST)="010" and data_av(EAST)='1' else

credit_i(SOUTH) when tab_in(EAST)="011" and data_av(EAST)='1' else credit_i(LOCAL) when tab_in(EAST)="100" and data_av(EAST)='1' else '0';

--- -- PORTA WEST

---

tx(WEST) <= data_av(EAST) when tab_out(WEST)="000" and free(WEST)='0' else data_av(NORTH) when tab_out(WEST)="010" and free(WEST)='0' else data_av(SOUTH) when tab_out(WEST)="011" and free(WEST)='0' else data_av(LOCAL) when tab_out(WEST)="100" and free(WEST)='0' else '0';

data_out(WEST) <= data_in(EAST) when tab_out(WEST)="000" and free(WEST)='0' else data_in(NORTH) when tab_out(WEST)="010" and free(WEST)='0' else

data_in(SOUTH) when tab_out(WEST)="011" and free(WEST)='0' else data_in(LOCAL) when tab_out(WEST)="100" and free(WEST)='0' else (others=>'0');

data_ack(WEST) <= credit_i(EAST) when tab_in(WEST)="000" and data_av(WEST)='1' else credit_i(NORTH) when tab_in(WEST)="010" and data_av(WEST)='1' else

credit_i(SOUTH) when tab_in(WEST)="011" and data_av(WEST)='1' else credit_i(LOCAL) when tab_in(WEST)="100" and data_av(WEST)='1' else '0';

--- -- PORTA NORTH

---

tx(NORTH) <= data_av(EAST) when tab_out(NORTH)="000" and free(NORTH)='0' else data_av(WEST) when tab_out(NORTH)="001" and free(NORTH)='0' else data_av(SOUTH) when tab_out(NORTH)="011" and free(NORTH)='0' else data_av(LOCAL) when tab_out(NORTH)="100" and free(NORTH)='0' else '0';

data_out(NORTH) <= data_in(EAST) when tab_out(NORTH)="000" and free(NORTH)='0' else data_in(WEST) when tab_out(NORTH)="001" and free(NORTH)='0' else

data_in(SOUTH) when tab_out(NORTH)="011" and free(NORTH)='0' else data_in(LOCAL) when tab_out(NORTH)="100" and free(NORTH)='0' else (others=>'0');

--- -- PORTA SOUTH

---

tx(SOUTH) <= data_av(EAST) when tab_out(SOUTH)="000" and free(SOUTH)='0' else data_av(WEST) when tab_out(SOUTH)="001" and free(SOUTH)='0' else data_av(NORTH) when tab_out(SOUTH)="010" and free(SOUTH)='0' else data_av(LOCAL) when tab_out(SOUTH)="100" and free(SOUTH)='0' else '0';

data_out(SOUTH) <= data_in(EAST) when tab_out(SOUTH)="000" and free(SOUTH)='0' else data_in(WEST) when tab_out(SOUTH)="001" and free(SOUTH)='0' else

data_in(NORTH) when tab_out(SOUTH)="010" and free(SOUTH)='0' else data_in(LOCAL) when tab_out(SOUTH)="100" and free(SOUTH)='0' else (others=>'0');

data_ack(SOUTH) <= credit_i(EAST) when tab_in(SOUTH)="000" and data_av(SOUTH)='1' else credit_i(WEST) when tab_in(SOUTH)="001" and data_av(SOUTH)='1' else

credit_i(NORTH) when tab_in(SOUTH)="010" and data_av(SOUTH)='1' else credit_i(LOCAL) when tab_in(SOUTH)="100" and data_av(SOUTH)='1' else '0';

Referências

Documentos relacionados

Como o objetivo deste trabalho vai além de criar uma estação meteorológica para coletar dados de volume da chuva, direção e velocidade do vento, nível de radiação

De acordo com o texto, a resposta do Papagaio ao questionamento do Leão não pode ser considerada uma reafirmação da supremacia do Leão por ser uma simples repetição da

Dispõe sobre os crimes de &#34;lavagem&#34; ou ocultação de bens, direitos e valores; a prevenção da utilização do sistema financeiro para os ilícitos previstos nesta Lei; cria

Verificou-se que houve influência significativa na performance do teste de flexão de braço, atividade realizada após a corrida de 12 minutos, comparando com o mesmo teste em que

25 Centro Educacional Universitário Irregular / Portaria Vencida LESTE. 26 Centro Educacional Villa Joie Regular /

a escola Maalelplo 4o Baqalra Sexo masculino Preliminares Bocaina, bairro Ferreiras, bairro Provisória Boquira, villa Sexo feminino Preliminar Boquira, villa Mixta

Com o ambiente e realidade laboral descritas, o enfermeiro oncológico, após algum tempo deixa de se reconhecer como se reconhecia no inicio da sua carreira, permitindo uma

O Programa Rede Regional de Luta contra o Tráfico de Crianças e Adolescentes para Fins de Exploração Sexual na Região do MERCOSUL é resultado de um acordo assinado entre