[verilog][n00b] Tratando de implementar un bus de datos

360 views
Skip to first unread message

Carlos

unread,
Aug 13, 2016, 7:36:15 AM8/13/16
to FPGA-WARS: explorando el lado libre

Que tal,
Ya que por el momento (creo) que icestudio no soporta este tipo de datos (buses) estuve tratando de implementar un bus de datos, su función es la de ser el select de un multiplexor, se me ocurrió implementarlo así (imagen de arriba). La función del registro _sel es concatenar las entradas sel1 y sel0, siendo sel1 el bit más significativo, para seleccionar la entrada del multiplexor que queremos que este presente en la salida.
La verificación no me marca ningún error pero no se si esa implementación es correcta. Aun no se crear los testbench así que por el momento desearía escuchar su feedback sobre la implementación :D.

Adjunto el proyecto configurado para usar la iceStick por si lo quieren revisar más de cerca haha, no es nada al lado del ACC de obijuan pero por algo se empieza xD.

Saludos





mux_4_1.ice

Obijuan

unread,
Aug 13, 2016, 12:36:24 PM8/13/16
to FPGA-WARS: explorando el lado libre

Genial Carlos!

  Así es como yo también estoy implementando los buses de datos en icestudio 0.2, mientras se implementa el soporte en la 0.3

Te comento algunas cosas:

1) Los assign tienen que estar fuera de always, ya que son conexiones de cables

2) Para la entrada usa cables (wire) en vez de registros

3) La salida de valores en un circuito combinacional (dentro de always) se hace con "=" (en vez de con <=). Si es secuencial (depende del reloj), entonces se usa <=

Este código sería más correcto:

reg _o;
wire [1:0] _sel;

assign _sel = {sel1, sel0};

always @(*) begin
    case(_sel)
        0: _o = in0;
        1: _o = in1;
        2: _o = in2;
        3: _o = in3;
        default: _o = in0;
    endcase
end

assign o = _o;


Aprovecho y adjunto el mismo circuito para una icezum. Al tener 2 switches es muy fácil de probar el mux :-)


Gran aportación!  Gracias!!  :-)

Saludos, Obijuan
mux_4_1-icezum.ice
mux-2-1-icestudio-icezum.png

Carlos 47

unread,
Aug 13, 2016, 2:42:54 PM8/13/16
to fpga-wars-explora...@googlegroups.com
Hola Obijuan,
Gracias por las correcciones, adjunto el nuevo proyecto corregido, le puse compuertas NOT a la salida del Input-Config para que tengan un 1 lógico en las entradas sel del mux cuando se presione el boton. El mux lo había basado en el código de tu wiki [1].

Traté de hacer el mismo proyecto creando el archivo verilog, la asignacion de pines y test bench, pero no se como se le asignan las pull-up de forma escrita ;(.

Saludos

[1] https://github.com/Obijuan/open-fpga-verilog-tutorial/wiki/Cap%C3%ADtulo-11%3A-Multiplexor-de-2-a-1

--
Has recibido este mensaje porque estás suscrito al grupo "FPGA-WARS: explorando el lado libre" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el-lado-libre+unsubscribe@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a fpga-wars-explorando-el-lado-li...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/26264969-ee94-4b67-8f98-5be4d5e231fe%40googlegroups.com.

Para acceder a más opciones, visita https://groups.google.com/d/optout.

mux_4_1.ice
muxice.png

Carlos 47

unread,
Aug 13, 2016, 2:59:18 PM8/13/16
to fpga-wars-explora...@googlegroups.com
Ahora traté de hacer un demux 1:4, no me marca errores la verificación pero no estoy seguro del bloque always, ¿se puede quitar y solo hacer assign _o[_sel] = in0; ?

Adjunto el proyecto para la iceStick, aun no lo checo en real, tengo que buscar el pinout de la tarjeta :D

Saludos

Para publicar en este grupo, envía un correo electrónico a fpga-wars-explorando-el-lado-lib...@googlegroups.com.
demuxice.png
demux_1_4.ice

Carlos 47

unread,
Aug 13, 2016, 4:48:18 PM8/13/16
to fpga-wars-explora...@googlegroups.com
Parezco spam xD pero tenia mal el proyecto del mux, los bloques Input-Config ya tiene por dentro el NOT que había puesto por fuera, así que solo teniendo el Input-Config y presionado el boton ya tenemos un 1 lógico en la entrada.

Adjunto el proyecto actualizado, además puse un 0 lógico en los demás LEDs de la placa.

Saludos
-C

El 13 de agosto de 2016, 13:59, Carlos 47<carlos.san...@gmail.com> escribió:
Ahora traté de hacer un demux 1:4, no me marca errores la verificación pero no estoy seguro del bloque always, ¿se puede quitar y solo hacer assign _o[_sel] = in0; ?

Adjunto el proyecto para la iceStick, aun no lo checo en real, tengo que buscar el pinout de la tarjeta :D

Saludos
mux_4_1.ice
muxice.png

Carlos 47

unread,
Aug 13, 2016, 5:29:56 PM8/13/16
to fpga-wars-explora...@googlegroups.com
Bueh, ahora ya comprobé que funciona el demux 1:4, seguro se puede mejorar pero no se me ocurre como, dejo la nueva implementación.

El código:

reg [3:0] _o;

wire [1:0] _sel;

assign _sel = {sel1, sel0};

assign out0 = _o[0];
assign out1 = _o[1];
assign out2 = _o[2];
assign out3 = _o[3];

always@(*) begin
    case(_sel)
    0: _o = {3'b000, in0};
    1: _o = {2'b00, in0, 1'b0};
    2: _o = {1'b0, in0, 2'b00};
    3: _o = {in0, 3'b000};
    default: _o = {3'b000, in0};
    endcase
end


Saludos

El 13 de agosto de 2016, 15:48, Carlos 47<carlos.san...@gmail.com> escribió:
Parezco spam xD pero tenia mal el proyecto del mux, los bloques Input-Config ya tiene por dentro el NOT que había puesto por fuera, así que solo teniendo el Input-Config y presionado el boton ya tenemos un 1 lógico en la entrada.

Adjunto el proyecto actualizado, además puse un 0 lógico en los demás LEDs de la placa.

Saludos
-C
demuxice.png
demux_1_4.ice

Carlos

unread,
Aug 14, 2016, 6:25:55 PM8/14/16
to FPGA-WARS: explorando el lado libre
Que tal, me parece que la siguiente implementación es mejor para el demux:

reg [3:0] _o;
wire [1:0] _sel;

assign _sel = {sel1, sel0};

assign out0 = _o[0];
assign out1 = _o[1];
assign out2 = _o[2];
assign out3 = _o[3];

always@(*) begin
    _o = in0 << _sel;
end

Sintetiza y funciona bien, lo revise con la iceStick. ¿Qué implementación les parece mejor?, ¿Existen más formas de implementar el demux?.

Saludos, adjunto proyecto
demux2_1_4.ice
demuxshift.png

Obijuan

unread,
Aug 15, 2016, 4:07:53 AM8/15/16
to FPGA-WARS: explorando el lado libre
Hola Carlos!

Perdona la tardanza en la respuesta. Estoy de vacaciones con acceso a internet muy restringido. Ahora te respondo a todas las preguntas.

Tu implementación del demux es genial!  Ya habrás podido comprobar que hay infinidad de maneras de implementar las cosas. En cuanto a recursos, normalmente todas las implementaciones ocupan lo mismo. Una vez que el sintetizador infiere que se trata de un demux, lo implementa de la forma más óptima. Así que el cómo codificarlo en Verilog es una cuestión de gustos del diseñador.

A mí me gusta el estilo compacto

Este demux todavía se puede hacer más compacto

* Simplificación 1:  Uso del operador de concatenación {}  para asignar _o a la salida en una sola línea

El bloque código de icestudio quedaría así:


reg [3:0] _o;
wire [1:0] _sel;

assign _sel = {sel1, sel0};

assign {out3,out2,out1,out0} = _o;


always@(*) begin
    _o = in0 << _sel;
end

* Simplificación 2: Sustitución de Always @(*) por assign

Al ser un circuito combinación sencillo, se puede integrar directamente en un assign, sin necesidad de definir un bloque combinacional con always. Este código sería totalmente equivalente:


reg [3:0] _o;
wire [1:0] _sel;

assign _sel = {sel1, sel0};

assign {out3,out2,out1,out0} = _o;

assign  _o = in0 << _sel;

* Simplificación 3:  Combinar los dos assign anteriores y eliminar la variable temporal _o

  En la simplificación eiminamos la variable temporal _o y usamos un assign:


wire [1:0] _sel;

assign _sel = {sel1, sel0};

assign {out3,out2,out1,out0} = in0 << _sel;

Y esto nos conduce a la última simplificación:

* Simplificación 4: Un assign para unirlos a todos

Podemos eliminar el cable _sel y meter las dos entradas de selección directamente en el assign:

assign {out3,out2,out1,out0} = in0 << {sel1, sel0};

Insisto, los recursos consumidos son los mismos. El usar un código u otro depende de nuestras preferencias.
Normalmente en Verilog se prefiere que todo sea lo más compacto posible (similar a C).
En VHDL sin embargo, la preferencia es por la "verbosidad"

Pero es cuestión de los gustos del diseñador

Saludos, Obijuan

Obijuan

unread,
Aug 15, 2016, 4:36:03 AM8/15/16
to FPGA-WARS: explorando el lado libre


El sábado, 13 de agosto de 2016, 20:42:54 (UTC+2), Carlos escribió:
Hola Obijuan,
Gracias por las correcciones, adjunto el nuevo proyecto corregido, le puse compuertas NOT a la salida del Input-Config para que tengan un 1 lógico en las entradas sel del mux cuando se presione el boton.

Creo que en otro mensaje ya lo has decubierto. Esto ya se hace en input-config: Se configura el pull-up y se añade un NOT para que la lógica sea positiva:  0-pulsador NO apretado. 1-Pulsador apretado.  La lógica positiva es mucho más intuitiva para la gente que empieza

 
El mux lo había basado en el código de tu wiki [1].


Si. El tutorial lo hice hace 1 año, y mi verilog ha mejorado mucho desde entonces muahahahahahaha.  Tengo en el TODO cambiarlo, pero no me da la vida. Los TODOs de los frikis crecen de forma exponencial, de manera que nunca tendremos suficiente tiempo en nuestra vida para poder hacer todo lo que tenemos pendiente. Yo ya lo he asimilado y me resigno  jajajjaajajjjajajaajja
 

Traté de hacer el mismo proyecto creando el archivo verilog, la asignacion de pines y test bench, pero no se como se le asignan las pull-up de forma escrita ;(.

Te paso este código de ejemplo:  Es un hola mundo que configura el pul-up de un pin de entrada y saca por el led la entrada negada (lógica positiva)

module config(inout SW1,
            output wire LED0);

//-- Entrada a usar en nuestro circuito, con el pull-up activado
wire din;

//-- Sacar por el led la entrada negada (logica positiva)
assign LED0 = ~din;

//-- Bloque I/O.
//-- Entrada: señal SW del pin de la FPGA
//-- Salida: din: Señal con pull-up activado, lista para usarse
SB_IO #(
    .PIN_TYPE(6'b 1010_01),
    .PULLUP(1'b 1)
) io_pin (
    .PACKAGE_PIN(SW1),
    .OUTPUT_ENABLE(1'b0),
    .D_OUT_0(1'b0),
    .D_IN_0(din)
);

endmodule

Lo que se hace es instanciar un componente de la biblioteca de Lattice, el SB_IO, que permite configurar el pull-up (y también gestionar los pines de entrada/salida). Este componente lo tiene el Yosys  incorporado (no hay que añadir nada adicional)

Saludos, Obijuan
 

Obijuan

unread,
Aug 15, 2016, 4:37:11 AM8/15/16
to FPGA-WARS: explorando el lado libre
Perfecto! :-)


El sábado, 13 de agosto de 2016, 22:48:18 (UTC+2), Carlos escribió:
Parezco spam xD pero tenia mal el proyecto del mux, los bloques Input-Config ya tiene por dentro el NOT que había puesto por fuera, así que solo teniendo el Input-Config y presionado el boton ya tenemos un 1 lógico en la entrada.

Adjunto el proyecto actualizado, además puse un 0 lógico en los demás LEDs de la placa.

Saludos
-C
Para publicar en este grupo, envía un correo electrónico a fpga-wars-explorando-el-lado-li...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages