testbench em VHDL para bus inout

Linguagem descritiva de hardware

Moderadores: 51, guest2003

testbench em VHDL para bus inout

Mensagempor chrdcv » 11 Jan 2014 19:20

Saudações pessoal!

Estou descrevendo um circuito em VHDL em que quatro cartões SAM são lidos e escritos (não simultaneamente) através de um barramento correspondente (EPLD_SAM_DIO_IO[0...3]), mediante a seleção de escrita/leitura dada por sam_dio[0...3], onde os dados de escrita e leitura de um dos cartões selecionado será "copiado" para a UART, através da saída de transmissão de dados: "uart_xmit" e entrada: "uart-recv".

O circuito funciona como um bridge entre a UART e o pino de dados do cartão. O trecho abaixo exibe a descrição. Conforme podem notar, os pinos EPLD_SAM_DIO(0...3) são os pinos de escrita e leitura no cartão (conectado à EPLD), uart_xmit é a saída de transmissão da UART, uart_recv é entrada de recepção da UART. sam_dio(0...3) correspondem as seleções do cartão a ser interfaceado, bem como se será escrita ou leitura.

Realizei a descrição primeiramente utilizando o GHDL e depois o Quartus. A síntese foi feita no Quartus sem maiores problemas ou warnings, mas fazer o testbench, não consigo simular corretamente o comportamento de entrada/saída do pino EPLD_SAM_DIO_IO(0...3). Somente um caso funciona.

Alguém teria uma dica?

Código: Selecionar todos
 uart_xmit <= EPLD_SAM_DIO_IO(0) when sam_dio(0) = '0' and
                                         sam_dio(1) = '1' and
                                         sam_dio(2) = '1' and
                                         sam_dio(3) = '1' else
                 EPLD_SAM_DIO_IO(1) when sam_dio(0) = '1' and
                                         sam_dio(1) = '0' and
                                         sam_dio(2) = '1' and
                                         sam_dio(3) = '1' else
                 EPLD_SAM_DIO_IO(2) when sam_dio(0) = '1' and
                                         sam_dio(1) = '1' and
                                         sam_dio(2) = '0' and
                                         sam_dio(3) = '1' else
                 EPLD_SAM_DIO_IO(3) when sam_dio(0) = '1' and
                                         sam_dio(1) = '1' and
                                         sam_dio(2) = '1' and
                                         sam_dio(3) = '0' else '1';

        EPLD_SAM_DIO_IO(0) <= EPLD_UART_RECV_I when sam_dio(0) = '1' and
                                                   sam_dio(1) = '0' and
                                                sam_dio(2) = '0' and
                                                sam_dio(3) = '0' else 'Z';

        EPLD_SAM_DIO_IO(1) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and
                                                   sam_dio(1) = '1' and
                                                sam_dio(2) = '0' and
                                                sam_dio(3) = '0' else 'Z';

        EPLD_SAM_DIO_IO(2) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and
                                                   sam_dio(1) = '0' and
                                                sam_dio(2) = '1' and
                                                sam_dio(3) = '0' else 'Z';

        EPLD_SAM_DIO_IO(3) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and
                                                   sam_dio(1) = '0' and
                                                sam_dio(2) = '0' and
                                                sam_dio(3) = '1' else 'Z';
Seu Madruga: "O trabalho não é ruim, ruim é ter que trabalhar"
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

Re: testbench em VHDL para bus inout

Mensagempor andre_luis » 11 Jan 2014 20:12

Já faz uma década que não mexo com VHDL, mas pra facilitar na investigação, coloquei numa linha os comandos que pertencem á mesma condição.
Então, exatamente que sequencias abaixo não estão sendo executadas quando deveriam ?


EPLD_SAM_DIO_IO(0) when sam_dio(0) = '0' and sam_dio(1) = '1' and sam_dio(2) = '1' and sam_dio(3) = '1' else
EPLD_SAM_DIO_IO(1) when sam_dio(0) = '1' and sam_dio(1) = '0' and sam_dio(2) = '1' and sam_dio(3) = '1' else
EPLD_SAM_DIO_IO(2) when sam_dio(0) = '1' and sam_dio(1) = '1' and sam_dio(2) = '0' and sam_dio(3) = '1' else
EPLD_SAM_DIO_IO(3) when sam_dio(0) = '1' and sam_dio(1) = '1' and sam_dio(2) = '1' and sam_dio(3) = '0' else '1';

EPLD_SAM_DIO_IO(0) <= EPLD_UART_RECV_I when sam_dio(0) = '1' and sam_dio(1) = '0' and sam_dio(2) = '0' and sam_dio(3) = '0' else 'Z';
EPLD_SAM_DIO_IO(1) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and sam_dio(1) = '1' and sam_dio(2) = '0' and sam_dio(3) = '0' else 'Z';
EPLD_SAM_DIO_IO(2) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and sam_dio(1) = '0' and sam_dio(2) = '1' and sam_dio(3) = '0' else 'Z';
EPLD_SAM_DIO_IO(3) <= EPLD_UART_RECV_I when sam_dio(0) = '0' and sam_dio(1) = '0' and sam_dio(2) = '0' and sam_dio(3) = '1' else 'Z';



Obs.: Tive de retirar a formatação CODE porque o texto não cabia em cada linha da mensagem.


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: testbench em VHDL para bus inout

Mensagempor chrdcv » 13 Jan 2014 11:06

André, obrigado pelo teu interesse e atenção ao identar o código para melhor leitura e interpretação!

Como mencionado no post inicial, eu não tenho problema com a descrição passada nem com a síntese efetuada pelo Quartus; meu problema encontra-se na escrita de um testbench que simule o comportamento do barramento: EPLD_SAM_DIO_IO(0...3) ora como entrada, ora como saída, dependendo da configuração dada por sam_dio(0...3).

Att.
chrdcv
Seu Madruga: "O trabalho não é ruim, ruim é ter que trabalhar"
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

Re: testbench em VHDL para bus inout

Mensagempor andre_luis » 14 Jan 2014 06:46

Rabisca uma idéia do que precisa num diagrama.
Em princípio não deveria ser tão complicado, pois afinal parece ser uma espécie de buffer bidirecional controlado por um mux.

Não seria algo tipo assim ?

Código: Selecionar todos
EPLD_SAM_DIO_IO(0) = '0' ;
EPLD_SAM_DIO_IO(1) = '0' ;
EPLD_SAM_DIO_IO(2) = '0' ;
EPLD_SAM_DIO_IO(3) = '0' ;

wait for 10 ns;

sam_dio(0) = '0' ;
sam_dio(1) = '1' ;
sam_dio(2) = '1' ;
sam_dio(3) = '1' ;

wait for 10 ns;


Pra testar por exemplo escrita do valor da EPLD_SAM_DIO_IO(0) no uart_xmit...

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: testbench em VHDL para bus inout

Mensagempor chrdcv » 14 Jan 2014 12:01

André, mais uma vez obrigado pelo suporte!

Notei que uma mensagem que tu postou simplesmente "sumiu"; certamente devido a migração do servidor do fórum.

Ontem, alterei um pouco a descrição para ficar mais "enxuta", observei novamente o que foi gerado pela síntese (RTL) e pude perceber que ao invés do uso de portas lógicas, multiplexadores foram utilizados (certamente devido ao uso do std_logc_vector (3 downto 0) para comparação).

Código: Selecionar todos
uart_xmit <= EPLD_SAM_DIO_IO(0) when sam_dio_sel = "0111" else
                 EPLD_SAM_DIO_IO(1) when sam_dio_sel = "1011" else
                 EPLD_SAM_DIO_IO(2) when sam_dio_sel = "1101" else
                 EPLD_SAM_DIO_IO(3) when sam_dio_sel = "1110" else '1';

EPLD_SAM_DIO_IO(0) <= EPLD_UART_RECV_I when sam_dio_sel = "1000" else 'Z';
EPLD_SAM_DIO_IO(1) <= EPLD_UART_RECV_I when sam_dio_sel = "0100" else 'Z';
EPLD_SAM_DIO_IO(2) <= EPLD_UART_RECV_I when sam_dio_sel = "0010" else 'Z';
EPLD_SAM_DIO_IO(3) <= EPLD_UART_RECV_I when sam_dio_sel = "0001" else 'Z';


Estou alterando umas partes do testbench, vou ver se posto algo esclarecedor ainda hoje ou amanhã...

chrdcv
Seu Madruga: "O trabalho não é ruim, ruim é ter que trabalhar"
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

Re: testbench em VHDL para bus inout

Mensagempor msamsoniuk » 14 Jan 2014 22:27

tem um truque em VHDL que facilita 1000% a sua vida: aprender verilog! hahaha (:

Imagem

http://www.asic-world.com/verilog/verilog_one_day.html
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: testbench em VHDL para bus inout

Mensagempor chrdcv » 15 Jan 2014 10:30

Putz, devia ter escutado vc em outros posts...

Mas como faço um testbench em verilog para simular um bus de I/O?
Seu Madruga: "O trabalho não é ruim, ruim é ter que trabalhar"
Avatar do usuário
chrdcv
Dword
 
Mensagens: 1580
Registrado em: 13 Out 2006 14:13

Re: testbench em VHDL para bus inout

Mensagempor msamsoniuk » 15 Jan 2014 12:19

chrdcv escreveu:Putz, devia ter escutado vc em outros posts...

Mas como faço um testbench em verilog para simular um bus de I/O?


eu nao entendi exatamente o que vc precisa, mas imagino que eh algo relacionado com um bus bi-direcional neh... bom, segue um exemplo que faz R/W em uma memoria interna 256 bytes:

Código: Selecionar todos
// memoria 256 bytes, leitura assincrona, escrita sincrona com WR=1
module ble(input CLK, input WR, input [7:0] ADDR, inout [7:0] DATA);
  reg [7:0] MEM [0:255];

  assign DATA = WR ? MEMO : '8bzzzz_zzzz;

  always@(posedge CLK)
  begin
    if(WR) // write
      MEM[ADDR] <= DATA;
  end

endmodule

// teste para o modulo bleh
module bleh_test
  reg CLK = 0;
  reg [8:0] STATE = 0;

  integer i;
  initial
  begin
    for(i=0;i!=100000;i=i+1) // 100 mil passos de simulacao
    begin
      #30 CLK = 0; // clock de 60 nanosegundos
      #30 CLK = 1;
    end
  end

  always@(posedge CLK)
  begin
    STATE <= STATE+1; // tipica maquina de estado incremental
  end

  wire WR = STATE[8];
  wire [7:0] DATA = WR ? STATE[7:0] : 4'bzzzz;
  wire [7:0] ADDR = STATE[7:0];

  bleh bleh0(CLK,WR,ADDR,DATA); // aqui eh onde instancia o modulo a ser testado

endmodule


o teste eh bem simples, basicamente ele grava e le alternadamente todos os 256 enderecos. note que eu costumo usar o initial apenas para gerar CLK e faco o resto sintetizavel (normalmente eu construo o sistema inteiro nos meus testes, entao fazer tudo sintetizavel significa que eu posso reaproveitar partes no futuro)... nao precisa, mas eh eh bom para acostumar a sempre fazer sintetizavel. bom, durante a escrita (STATE[8]==1), ele grava como dado o mesmo valor do endereco e faz isso para os 256 enderecos. mas eh possivel mudar isso na definicao do wire DATA, por exemplo, no lugar de STATE[7:0] usar ~STATE[7:0] vai gravar o inverso. o importante eh observar a consistencia de WR fora e dentro do modulo, pq os lados precisam entrar em tri-state alternadamente, conforme o barramento alterna de input para output e vice-versa.

ah! eu nao testei o codigo... depois eu testo para ver se tem algum bug! (:
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: testbench em VHDL para bus inout

Mensagempor andre_luis » 15 Jan 2014 17:57

chrdcv escreveu:...Mas como faço um testbench em verilog para simular um bus de I/O?


O que eu havia entendido no título e na primeira postagem é que a linguagem usada é o VHDL, e não o Verilog.
Bom, o que eu faria seria algo assim ( em VHDL ) :

Código: Selecionar todos
stimulus : process is
begin

-- teste do recebimento
-----------------------
EPLD_SAM_DIO_IO(0) <= "00000000"          ;  -- carrega valor 0 em EPLD_SAM_DIO_IO(0)
sam_dio_sel <= "0111" ; wait for 10 ns    ;  -- uart_xmit recebe o EPLD_SAM_DIO_IO(0)

EPLD_SAM_DIO_IO(1) <= "00000001"          ;  -- carrega valor 1 em EPLD_SAM_DIO_IO(1)
sam_dio_sel <= "1011" ; wait for 10 ns    ;  -- uart_xmit recebe o EPLD_SAM_DIO_IO(2)

EPLD_SAM_DIO_IO(2) <= "00000010"          ;  -- carrega valor 2 em EPLD_SAM_DIO_IO(2)
sam_dio_sel <= "1101" ; wait for 10 ns    ;  -- uart_xmit recebe o EPLD_SAM_DIO_IO(3)

EPLD_SAM_DIO_IO(3) <= "00000011"          ;  -- carrega valor 3 em EPLD_SAM_DIO_IO(3)
sam_dio_sel <= "1110" ; wait for 10 ns    ;  -- uart_xmit recebe o EPLD_SAM_DIO_IO(4)

wait for 10 ns                            ;  -- delay adicional p/a destacar na simulacao

-- teste do envio
-----------------
EPLD_UART_RECV_I   <= "00000100"          ;  -- carrega valor 4 em EPLD_UART_RECV_I
sam_dio_sel(0) <= "1000" ; wait for 10 ns ;  -- EPLD_SAM_DIO_IO(0) recebe o valor de uart_recv

EPLD_UART_RECV_I   <= "00000101"          ;  -- carrega valor 5 em EPLD_UART_RECV_I
sam_dio_sel(1) <= "0100" ; wait for 10 ns ;  -- EPLD_SAM_DIO_IO(1) recebe o valor de uart_recv

EPLD_UART_RECV_I   <= "00000110"          ;  -- carrega valor 6 em EPLD_UART_RECV_I
sam_dio_sel(2) <= "0010" ; wait for 10 ns ;  -- EPLD_SAM_DIO_IO(2) recebe o valor de uart_recv

EPLD_UART_RECV_I   <= "00000111"          ;  -- carrega valor 7 em EPLD_UART_RECV_I
sam_dio_sel(3) <= "0001" ; wait for 10 ns ;  -- EPLD_SAM_DIO_IO(3) recebe o valor de uart_recv

wait for 10 ns                            ;  -- delay adicional p/a destacar na simulacao

wait                                      ;
end process stimulus   


Como uma colher de chá, segue também um rascunho do que entendi do seu circuito:

VHDL.png


+++
Você não está autorizado a ver ou baixar esse anexo.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: testbench em VHDL para bus inout

Mensagempor msamsoniuk » 15 Jan 2014 20:05

eh q ele perguntou como faria para simular um bus de IO bi-direcional em verilog e eu daih montei um exemplo para ele ver. eu nao arrisquei montar o circuito dele pq achei que era um fragmento combinacional e que havia muito mais circuitos em volta... por exemplo, em verilog os buffers de IO podem ser tipo wire (input, output e inout) ou reg (output), q jah sao referencias a elementos low-level, mas em VHDL o buraco eh mais embaixo e eu sempre vi os caras referenciando explicitamente buffers de IO, pq a logica usa um tipo diferente dos tipos de IO... enfim, se a logica for apenas aquilo, ficaria isso aqui:

Código: Selecionar todos
module chrdcv(input UART_RECV, output UART_XMIT, input [3:0] SAM_DIO_SEL, inout [3:0] EPLD_SAM_DIO_IO)

  assign UART_XMIT  =
                                        SAM_DIO_SEL==4'b0111 ? EPLD_SAM_DIO_IO[0] :
                                        SAM_DIO_SEL==4'b1011 ? EPLD_SAM_DIO_IO[1] :
                                        SAM_DIO_SEL==4'b1101 ? EPLD_SAM_DIO_IO[2] :
                                        SAM_DIO_SEL==4'b1101 ? EPLD_SAM_DIO_IO[3] :
                                         1'b1;

  assign EPLD_SAM_DIO_IO[0] <= SAM_DIO_SEL==4'b0100 ? UART_RECV : 1'bz;
  assign EPLD_SAM_DIO_IO[1] <= SAM_DIO_SEL==4'b0100 ? UART_RECV : 1'bz;
  assign EPLD_SAM_DIO_IO[2] <= SAM_DIO_SEL==4'b0010 ? UART_RECV : 1'bz;
  assign EPLD_SAM_DIO_IO[3] <= SAM_DIO_SEL==4'b0001 ? UART_RECV : 1'bz;

endmodule

module test_chrdcv;

  reg [3:0] SAM_DIO_SEL;
  reg [3:0] EPLD_SAM_IO_REG = 0;

  integer i;

  initial
  begin
    for(i=0;i!=10000;i=i+1)
      EPLD_SAM_IO_REG <= EPLD_SAM_IO_REG + 1;
  end

  wire UART_XMIT;
  wire UART_RECV = EPLD_SAM_IO_REG[0];
  wire [3:0] EPLD_SAM_DIO_IO = SAM_DIO_SEL[3]==1?EPLD_SAM_IO_REG:4'bzzzz;

  chrdcv chrdcv0(UART_RECV, UART_XMIT, SAM_DIO_SEL, EPLD_SAM_DIO_IO);

endmodule


enfim, alguma coisa assim. nao fica muito diferente de VHDL, mas deve ser o dialeto... eu particularmente tentaria fazer algo mais compacto:

Código: Selecionar todos
module chrdcv(input UART_RECV, output UART_XMIT, input RXSEL, input [1:0] SAM_DIO_SEL, inout [3:0] EPLD_SAM_DIO_IO)

  assign UART_XMIT  = RXSEL==1 ? EPLD_SAM_DIO_IO[SAM_DIO_SEL] : 1'b1;
  assign EPLD_SAM_DIO_IO <= RXSEL==0 ? (UART_RECV<<SAM_DIO_SEL) : 4'bzzzz;

endmodule


mas vendo apenas uma parte da logica fica dificil entender pq foi feito de determinada forma e se daria certo de outra.
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Re: testbench em VHDL para bus inout

Mensagempor andre_luis » 15 Jan 2014 20:41

msamsoniuk escreveu:...mas vendo apenas uma parte da logica fica dificil entender pq foi feito de determinada forma e se daria certo de outra.


Também pensei assim, mas depois caiu a ficha e lembrei que ele estava querendo apenas um testbench dos sinais externos.
Desse modo, dá pra atentar somente ás informações de fora da caixa-preta, como os sinais de controle e as entradas e saídas...


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ


Voltar para Verilog, VHDL, SystemC ( PLAs, CPLDs, FPGAs, etc... )

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 0 visitantes

x