Pin de E / S bidireccional en verilog

6

Estoy queriendo eventualmente conectar alguna memoria a mi fpga. Esto requerirá pines en el fpga que pueden leer datos y escribir la salida al ram.

Todavía estoy muy lejos de hacer algo de eso, pero como ejercicio de aprendizaje quería hacer un módulo simple en verilog que cuando una señal de dirección es '1' envía una señal a un pin, y cuando es '0' lee un valor de ese pin.

Pero no puedo hacer nada para compilar. No estoy completamente inexperto con verilog pero siento que me estoy perdiendo algo fundamental aquí en lugar de tener un simple error tipográfico en mi ejemplo.

Este código no se compila, estoy buscando la forma de hacerlo funcionar, o simplemente un indicador de lo que me falta fundamentalmente para hacer que las señales bidireccionales funcionen. Si me importa, estoy usando herramientas de xilinx y planeo sintetizar esto en un xc3s50 o similar.

// This doesn't compile...
module test(
    input  clock,           // The standard clock
     input  direction,  // Direction of io, 1 = set output, 0 = read input
     input  data_in,        // Data to send out when direction is 1
     output data_out,       // Result of input pin when direction is 0
     inout  io_port     // The i/o port to send data through
     );

always @(posedge clock)
begin

    // If direction is 1 then set 
    if (direction == 1)
    begin
        io_port <= data_out;
    end

    if (direction == 0)
    begin
         data_in <= io_port;
    end
end

endmodule

editar Los errores que recibo son -

ERROR:HDLCompilers:247 - "test.v" line 16 Reference to scalar wire 'io_port' is not a legal reg or variable lvalue
ERROR:HDLCompilers:106 - "test.v" line 16 Illegal left hand side of nonblocking assignment
ERROR:HDLCompilers:247 - "test.v" line 21 Reference to scalar wire 'data_in' is not a legal reg or variable lvalue
ERROR:HDLCompilers:106 - "test.v" line 21 Illegal left hand side of nonblocking assignment
    
pregunta John Burton

1 respuesta

8

Las entradas son en realidad "cableadas", por lo que no se pueden usar asignaciones de procedimiento / secuenciales (donde el lado izquierdo debe ser un registro). En términos generales:

  • entrada : internamente siempre debe ser de tipo net, externamente las entradas Se puede conectar a una variable de tipo reg o net.
  • salida : internamente puede ser de tipo net o reg, externamente las salidas deben ser Conectado a una variable de tipo net.
  • inout : internamente o externamente debe siempre ser tipo net, solo se puede conectar a un tipo de red variable.

Un enfoque común es tener una señal de "habilitación" para la salida de su entrada y conducir a alta impedancia si la salida no está habilitada. En su caso, la dirección está jugando ese papel.

Así que prueba esto en su lugar:

module test(
    input  clock,      // The standard clock
    input  direction,  // Direction of io, 1 = set output, 0 = read input
    input  data_in,    // Data to send out when direction is 1
    output data_out,   // Result of input pin when direction is 0
    inout  io_port     // The i/o port to send data through
    );

    reg a, b;    

    assign io_port  = direction ? a : 1'bz;
    assign data_out = b;

    always @ (posedge clk)
    begin
       b <= io_port;
       a <= data_in;
    end

end

endmodule

El hardware correspondiente al código anterior se vería así:

    
respondido por el vicatcu

Lea otras preguntas en las etiquetas