Autor Tema: Ejemplos Verilog  (Leído 59517 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Ejemplos Verilog
« en: 09 de Octubre de 2010, 16:42:36 »
A continuación mostraré una serie de ejemplos realizados satisfactoriamente en el kit de desarrollo Basys2 de Digilent, el cual utiliza un FPGA del tipo SPARTAN3E.

Con el siguiente VideoTutorial pueden comenzar a crear nuevos proyectos con el ISE de XILINX.

Indice
1. Operaciones bitwise (bit a bit).
2. Conexiones Internas Auxiliares
3. Multiplexores y Parametros
4. Módulos y Conexiones
5. Convertidores de código.
6. Maquinas de Estados Secuenciales
    6.1. Contador de corrida Libre
    6.2. Contador Modulable
    6.3. Contador de Anillo.
    6.4. Divisor de Reloj.
7. Controlador de display de 7 segmentos Completo.
8. Contador BCD de 0 a 9999.
9. Circuito Anti-Rebote
10. Generador de Pulso de Reloj
« Última modificación: 18 de Noviembre de 2010, 18:58:04 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Operaciones bitwise (bit a bit).
« Respuesta #1 en: 09 de Octubre de 2010, 17:42:36 »
Operaciones bitwise (bit a bit).
El primer ejemplo será acerca de las operaciones bitwise: OR, AND, XOR, NOR, NAND y XNOR. Verilog es un lenguaje que utiliza un sintaxis muy similar al lenguaje C.

Cabe mencionar que existen dos tipos de salidas:
  • Las salidas tipo wire que no almacenan valores y son utilizadas cuando la operación es de tipo Combinacional.
  • Las salidas Tipo reg que almacenan valores y son utilizadas cuando la operación es del Tipo secuencial.

A continuación muestro el módulo verilog de ejemplo que utiliza las distintas compuertas. Este módulo utilza 2 entradas: a y b que se conectaran a los interruptores sw0 y sw1, y 6 salidas z0, z1, z2, z3, z4 y z5 que se conectaran a los leds ld0 hasta ld5.
Código: [Seleccionar]
module compuertas(
    input a,        //Declaramos la entrada a
    input b,        //Declaramos la entrada b
    output z0,      //Declaramos la salida z0
    output z1,      //Declaramos la salida z1
    output z2,      //Declaramos la salida z2
    output z3,      //Declaramos la salida z3
    output z4,      //Declaramos la salida z4
    output z5       //Declaramos la salida z5
    );
    
assign z0=a|b;        //Asignamos la operacion OR a la salida z0
assign z1=a&b;       //Asignamos la operacion AND a la salida z1
assign z2=a^b;       //Asignamos la operacion XOR a la salida z2
assign z3=!(a|b);    //Asignamos la operacion NOR a la salida z3
assign z4=!(a&b);   //Asignamos la operacion NAND a la salida z4
assign z5=!(a^b);   //Asignamos la operacion XNOR a la salida z5

endmodule

Como se observa en el ejemplo anterior siempre sera necesario utilizar la palabra reservada assign para asignar los valores a salidas tipo wire.

En Verilog existen dos formas de declarar Nets, una de ellas es como hicimos anteriormente declarando cada una a la vez, la otra forma es declarar los Nets mediante buses. El ejemplo que se muestra a continuación muestra como hacer esto.

Código: [Seleccionar]
module compuertas(
    input [1:0]i,        //Declaramos el bus de entrada i
    output [5:0]z        //Declaramos el bus de salida z
    );
    
assign z[0]=|i;        //Asignamos la operacion OR a la salida z0
assign z[1]=&i;        //Asignamos la operacion AND a la salida z1
assign z[2]=^i;        //Asignamos la operacion XOR a la salida z2
assign z[3]=~|i;    //Asignamos la operacion NOR a la salida z3
assign z[4]=~&i;    //Asignamos la operacion NAND a la salida z4
assign z[5]=~^i;    //Asignamos la operacion XNOR a la salida z5

endmodule

Para simular nuestro módulo con el ISE de XILINX es necesario crear un nuevo archivo de simulación "Verilog Test Fixture" el cual tiene la misma terminación *.v que un módulo "Verilog".

Para simular el primer ejemplo utilizaremos el siguiente código.
Código: [Seleccionar]
`timescale 1ns / 1ps
module compuertas_prueba;

    // Inputs
    reg a;
    reg b;

    // Outputs
    wire z0;
    wire z1;
    wire z2;
    wire z3;
    wire z4;
    wire z5;

    // Instantiate the Unit Under Test (UUT)
    compuertas uut (
        .a(a),
        .b(b),
        .z0(z0),
        .z1(z1),
        .z2(z2),
        .z3(z3),
        .z4(z4),
        .z5(z5)
    );

    initial begin
        // Initialize Inputs
        a = 0;
        b = 0;
    end
    //Cada 50ns incrementar en uno la variable {a,b}.
    always #50 {a,b}={a,b}+1;
    
endmodule

En el ejemplo anterior observamos la sintaxis {a,b} que significa que concatenaremos los bit a y b para crear una nueva variable de 2 bits.

El siguiente paso será conectar el módulo creado en nuestro FPGA con el mundo exterior, para ello crearemos un archivo de implementacion *.ucf a partir de los datos brindados por el manual de referencia del BASYS2. En la figura siguiente podemos observar las conexiones del FPGA con el mundo exterior.


Por los momento utilizaremos el siguiente código para conectar el FPGA con los interruptores y leds, luego utilizaremos un archivo universal que nos brinda el fabricante.
Código: [Seleccionar]
net "a" loc = "p11";    #net a conectada al pin P11 del FPGA
net "b" loc = "l3";     #net b conectada al pin l3 del FPGA
net "z0" loc = "m5";    #net z0 conectada al pin m5 del FPGA
net "z1" loc = "m11";   #net z1 conectada al pin m11 del FPGA
net "z2" loc = "p7";    #net z2 conectada al pin p7 del FPGA
net "z3" loc = "p6";    #net z3 conectada al pin p6 del FPGA
net "z4" loc = "n5";    #net z4 conectada al pin n5 del FPGA
net "z5" loc = "n4";    #net z5 conectada al pin n4 del FPGA

Comentarios
« Última modificación: 16 de Octubre de 2010, 03:01:40 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #2 en: 10 de Octubre de 2010, 21:39:02 »
Conexiones internas auxiliares

Algo sumamente importante en todo programa es cuando necesitamos variables auxiliares, aunque en verilog se pueden utilizar algunos tipos de variables que usamos en C como int, estas son utilizadas para propósitos de preprocesamiento y no a como se hace comunmente en C. En la programación de hardware lo que se utiliza son conexiones auxiliares.

Las principales conexiones utilizadas en Verilog son:
  • Tipo wire que no almacenan valores y son utilizadas cuando la operación es de tipo Combinacional.
  • Tipo reg que almacenan valores y son utilizadas cuando la operación es del Tipo secuencial.
Si observamos lo anterior es sumamanete similar a los tipos de salidas.

Algo inportante de recoradar al prgramar en verilog es que estamos programando Hardware, es decir estamos realizando los módulos o circuitos que irán dentro de nuestro FPGA, a diferencia de la programación en C que es para que el dispositivo realice una secuencia de procesos los FPGA pueden realizar muchos procesos de forma paralela.

En el siguiente ejemplo conectaré una compuerta AND a las entradas a y b y luego conectaré su salida a una compuerta OR con la entrada c y la salida de la OR a la salida z. es decir:
z=ab+c

A continuación muestro el esquemático que se generaría despues de realizar el módulo verilog:

Uploaded with ImageShack.us

Y el código para realizar esto es el siguiente.
Código: [Seleccionar]
module codigo_wire(
    input a,
    input b,
    input c,
    output z
    );
wire aux;            //Declaramos la conexion aux de tipo wire

assign aux=a&b;    //asignamos a aux la salida de la compuerta AND entre a y b
assign z=aux|c;    //asignamos a z la salida de la compuerta OR entre aux y c.

endmodule

En el código anterior tambien podemos hacerlo de la siguiente manera.
Código: [Seleccionar]
assign z=a&b | c;
Las conexiones tipo wire o reg pueden ser buses al igual que las salidas y las entradas, a continuación se muestra un ejemplo.
Código: [Seleccionar]
wire [3:0]z;   //Declaramos las conexiones tipo bus-wire z
reg [1:0]y;    //Declaramos las conexiones tipo bus-reg y

Luego mostraré algunos ejemplos de máquinas secuenciales en las que se abordará de mejor manera las conexiones tipo reg.

Comentarios
« Última modificación: 07 de Noviembre de 2010, 19:14:27 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #3 en: 13 de Octubre de 2010, 20:08:12 »
Multiplexores

Citar
Un multiplexor es un circuito combinacional con 2^n líneas de entrada de datos, 1 línea de salida y n  entradas de selección. Las entradas de selección indican cual de estas líneas de entrada de datos es la que proporciona el valor a la línea de salida.
http://es.wikipedia.org/wiki/Multiplexor



En la figura anterior se muestra un multiplexor 2 a 1. Es decir, si el pin de selección es 0 entonces se conectará a la salida la entrada I0, pero si sel es 1 entonces se conectará a la salida la entrada I1. El código en verilog para lograr esto se muestra a continuación.

Código: [Seleccionar]
module mux2_1(
    input I0, //Declaramos la entrada I0
    input I1, //Delaramos la entrada I1
    input sel, //Declaramos la entrada sel
    output out //Declaramos la salida out
    );

assign out=sel?I1:I0; //Si sel es igual a 1 entonces out sera igual a I1
//De lo contrario out sera igual a I0
endmodule

Parametros
En muchos casos es necesario que nuestro módulo varíe con respecto a un parametro necesario. Por ejemplo si desearamos que nuestro multiplexor fuese de 4 a 1 entonces necesitaríamos declarar:
  • 4 entradas I0 hasta I3
  • 2 selectores S0 hasta S1
  • 1 salida Out



Para ello tendriamos el siguiente código
Código: [Seleccionar]
module mux4_1(
    input [3:0]I,        //Declaramos el bus de entrada I
    input [1:0]Sel,    //Declaramos el bus de entrada S
    output out            //Declaramos la salida out
    );
    
assign out= I[Sel];    //Out sera igual a la entrada correspondiente a la seleccion.
                            //por ejemplo si sel=1 entonces out=I[1]
endmodule

Pero si desearamos que fuese un multiplexor de 2^n entradas y una salida podemos hacerlo mediante parametros. El código siguiente muestra esto.

Código: [Seleccionar]
module mux2n_1 #(
parameter N=2)( //Declaramos el Parametro N=2
input [2**N-1:0]I, //Declaramos el bus I con pines desde 2^N-1 hasta 0 (si N=2 entonces 7:0)
input [N-1:0]Sel, //Declaramos el bus Sel con pines desde N-1 hasta 0 (si N=2 entonces 1:0)
output Out //Declaramos la Salida Out
   );
assign Out=I[Sel]; //Out sera igual a la entrada seleccionada.
//Por ejemplo si Sel=2 entonces Out sera igual a I[2]
endmodule

Ahora si deseamos realizar "N" multiplexores de 2 a 1 significaria que nuestro módulo tendría:
  • N entradas de datos a los que llamaremos A
  • N entradas de datos a los que llamaremos B
  • 1 entrada de selección
  • N salidas de datos.

A continuación se muestra el código para realizar esto.
Código: [Seleccionar]
module N_mux2_1 #(
parameter N=4)( //Declaramos Parametro N=4
input wire [N-1:0] a, //Declaramos bus de entrada a con N datos (si N=4 entonces tendremos [3:0]a).
input wire [N-1:0] b, //Declaramos bus de entrada b con N datos (si N=4 entonces tendremos [3:0]b).
input wire s, //Declaraos entrada de seleccion s
output wire [N-1:0] y //Declaramos bus de salida de datos y. (si N=4 entonces tendremos [3:0]y).
   );

assign y=!s?a:b; //si s=0 entonces el bus de salida y sera igual al bus de entrada a
//de lo contrario sera igual al bus de entrada b.
endmodule

Comentarios
« Última modificación: 07 de Noviembre de 2010, 19:11:51 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #4 en: 16 de Octubre de 2010, 02:30:59 »
Módulos
En la programación en C muchas veces es necesario reutilizar nuestro código, para hacer esto utilizamos funciones que reciben datos de entrada y entregan datos de salidas. Algo similar es Posible en la programación de Hardware, para esto se utilizan los módulos.

Un módulo es una pequeña parte del hardware del que está compuesto un sistema digital. Como se observó anteriormente la estructura básica de un módulo es la siguiente.

Código: [Seleccionar]
module <nombre del modulo> #(<parametros>) (<entradas y Salidas>);

<Conexiones auxiliares>

<Código del módulo>

endmodule

Cada módulo puede contener a otros módulos, pero solo existirá un módulo superior que contendrá a todos los demás módulos. Es decir existirá cierta Jerarquía en el programa.

El ejemplo siguiente muestra la conexión entre dos módulos que en su interior contienen la siguiente ecuación:

F=AB+C

A este módulo lo llamaremos ANDOR, como se observa en la siguiente figura tendrá 3 entradas A,B y C y una salida F.


By bigluis at 2010-10-10

A continuación se muestra el código para realizar el módúlo ANDOR:
Código: [Seleccionar]
module ANDOR (
    input A, B, C,  //declaracion de las entradas A, B y C
    output F        //Declaracion de la Salida F
    );
    
    assign F = (A & B) | C;
    
endmodule

Conexiones
En el módulo superior se realizarán las conexiones de los 2 módulos ANDOR donde
  • las entradas A,B y C del módulo U1 iran conectadas a las entradas J,K y L del módulo superior LOGIC.
  • la salida F del módulo U1 irá conectada a la salida P del módulo superior LOGIC.
  • las entradas B y C del módulo U2 iran conectadas a las entradas M y N del módulo superior LOGIC, mientras que la entrada A del módulo U1 irá conectada a la salida F del módulo U1.
  • la salida F del módulo U2 irá conectada a la salida Q del módulo superior LOGIC.


By bigluis at 2010-10-15

A continuación se muestra el código necesario para realizar las conexiones por orden para el módulo U1, es decir las conexiones se ubicarán en el orden que les corresponde a cada una de forma implícita. Y para el módulo U2 las conexiones se realizarán por nombre, es decir las conexiones se ubicaran en el lugar que le corresponde de manera explicita.
Código: [Seleccionar]
module LOGIC(
    input J, K, L, M, N,  //Declaracion de las entradas J, K, L, M y N
    output P, Q       //Declaracion de las salidas P y Q
    );
    
    ANDOR U1 (J, K, L, P);   //Creacion del modulo ANDOR-U1 conexionado por orden
    ANDOR U2 (.A(P), .B(M), .C(N), .D(Q)); //Creacion del modulo ANDOR-U2 conexionado por nombre
    
endmodule

Notas:
  • El módulo superior y los módulos internos pueden ir en archivos verilog distintos y luego agregarlos al proyecto o pueden ir en el Mismo Archivo
  • La ventaja de utilizar las conexiones por nombre es que podemos dejar desconectadas algunas entradas o salidas sin que se genere ningun problema.

Comentarios
« Última modificación: 07 de Noviembre de 2010, 19:09:56 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #5 en: 30 de Octubre de 2010, 01:12:14 »
Convertidores de Código

Un Convertidor de código es un circuito lógico que cambia los datos presentados en cierto tipo de código a otro código. La lista que se muestra a continuación muestra algunos de los convertidores más importantes:

   1. Hexadecimal a Siete Segmentos.
   2. BCD a binario.
   3. Binario a BCD.
   4. Binario a Código Gray.
   5. Código Gray a Binario.

Convertidor Hexadecimal a Siete segmentos.

Este circuito combinacional se encarga de transformar un código en formato hexadecimal de 4 bits a un código que se utilizará para mostrar el valor numérico del mismo en un display de 7 segmentos. A continuación se muestra los distintos números que se pueden mostrar en el display de 7 segmentos.


Existen dos tipos de display de 7 segmentos:


El kit Basys-2 tiene display del tipo Anodo Común, esto significa que para activar uno de sus LED será necesario conectar el Anodo-Común del display a Vcc y el Katodo del LED correspondiente a GND. Es decir cada LED se activa con un "0" lógico.

El código siguiente muestra como realizar la decodificación de hexadecimal a 7 segmentos mediante el uso de una tabla.
Código: [Seleccionar]
// Autor: Luis Alberto Vargas Tijerino.
// Create Date:    22:21:03 10/24/2010
// Module Name:    hex7seg
// Pais:  Nicaragua
module hex7seg(
   input [3:0] in,      //Declaramos el bus de entrada in
   output [6:0] a_to_g, //Declaramos el bus de salida a_to_g, para controlar los katodos.
   output [3:0] an      //Declaramos el bus de salida an, para controlar los andos.
   );

//Tabla para realizar la decodificacion de hex a 7-seg.
assign a_to_g= (sw==0)? 7'b000_0001:
               (sw==1)? 7'b100_1111:
               (sw==2)? 7'b001_0010:
               (sw==3)? 7'b000_0110:
               (sw==4)? 7'b100_1100:
               (sw==5)? 7'b010_0100:
               (sw==6)? 7'b010_0000:
               (sw==7)? 7'b000_1111:
               (sw==8)? 7'b000_0000:
               (sw==9)? 7'b000_0100:
               (sw=='hA)? 7'b000_1000:
               (sw=='hB)? 7'b110_0000:
               (sw=='hC)? 7'b011_0001:
               (sw=='hD)? 7'b100_0010:
               (sw=='hE)? 7'b011_0000:
                          7'b011_1000;
assign an=0;  //se encenderan todos los display.
endmodule

Para hacer que cada display trabaje por separado es necesario multiplexarlos en tiempo, esto es posible si utilizamos un contador y un quad mux 4 a 1, o podemos utilizar un contador de desplazamiento que valla seleccinando cada uno de los anodos del display y los datos a ser mostrados.

Comentarios
« Última modificación: 03 de Noviembre de 2010, 17:21:18 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #6 en: 30 de Octubre de 2010, 15:03:01 »
Máquinas de Estados Secuenciales.

Las máquinas de Estados Secuenciales son circuitos electrónicos que dependen de: una combianción de datos de entrata, una combinación de datos de salida y un el cambio producido por una señal de reloj, este cambio puede ser ascendende (flanco positivo o posedge) o descendente (flanco negativo o negedge).

El circuito de una máquina secuencial está compuesto por un conjunto de compuertas lógicas que forman parte de la retroalimentación de uno o más Flip-Flops.


A continuación se muestra la lista con algunas máquinas de estados finitos sumamente útiles.

   1. Contador o Divisor de Reloj.
   2. Registros de desplazamiento.
   3. Circuitos anti-rebote.
   4. etc...

Contador Digital

Contador de Corrida Libre
Un contador digital se encarga de seguir una secuencia de pasos ordenadas y simple. La figura que se muestra a continuación es un contador de 2 bits, es decir 2^2 = 4 estados.


Los contadores digitales támbien son sumamente utilizados para dividir la frecuencia de reloj por lo cual se les conoce como Divisores de reloj.

A continuación se muestra el código necesario para hacer un contador de 2 bits.
Código: [Seleccionar]
module contador(
    input clk,          //Declaramos la entrada clk
    input clr,          //Declaramos la entrada clr
    output reg [3:0] Q  //Declaramos el bus de salida Q.
    );

always @(posedge clk or posedge clr)
    if(clr)Q<=0;        //Si se activa clr el siguiente valor de Q sera 0
    else Q<=Q+1;        //De lo contrario el siguiente valor de Q sera Q+1.

endmodule

En la mayoría de los casos es necesario que nuestro contador sea ajustable, es decir, es necesario que tenga N bits de salida por lo tanto tendrá 2^N estados. A continuación se muestra el código necesario para realizar esto.
Código: [Seleccionar]
module contador#(
    parameter N=4)(       //Declaramos el parametro N=4
    input clk,            //Declaramos la entrada clk
    input clr,            //Declaramos la entrada clr
    output reg [N-1:0] Q  //Declaramos el bus de salida Q.
    );

always @(posedge clk or posedge clr)
    if(clr)Q<=0;        //Si se activa clr el siguiente valor de Q sera 0
    else Q<=Q+1;        //De lo contrario el siguiente valor de Q sera Q+1.

endmodule

Proyecto contN.rar

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:13:08 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #7 en: 30 de Octubre de 2010, 18:46:29 »
Contdador Modulable.
Estos Contadores realizan un conteo desde un valor incial, generalmente 0, hasta un valor final máximo, a continuación se muestra el código necesario para realizar un contador Mod=9, es decir este contará desde 0 hasta 9

Código: [Seleccionar]
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Autor:    Luis Alberto Vargas Tijerino.
//Fecha:    30 de Octubre de 2010.
//Pais:     Nicaragua.
//////////////////////////////////////////////////////////////////////////////////////////////////////
module cont_modN#(
   parameter N=3,       //Declaramos el Parametro N igual a 3.
   parameter Mod=9      //Declaramos el Parametro Mod igual a 9.
   )(
   input clk,           //Declaramos la entrada clk
   input clr,           //Declaramos la entrada clr
   output reg [N-1:0] Q //Declaramos el bus de salida tipo registro Q.
   );

always @(posedge clk or posedge clr) begin
   if(clr) Q<=0;          //Si se presiona clr el proximo valor de Q sera 0 de forma asincrona.
   else if(Q==Mod) Q<=0;  //De lo contrario Si Q es igual a Mod (en este caso 9) el proximo valor de Q sera 0.
   else Q<=Q+1;           //De lo contrario el proximo valor de Q sera 0.
end

endmodule

Para calcular el valor de N en el ejemplo anterior es necesario utilizar la siguiente formula:

$$N = \log _2 Mod = {{\ln Mod} \over {\ln 2}} = {{\ln 9} \over {\ln 2}} = 3.16

Ya que N solo puede tomar valores enteros, tomaremos el valor entero superior es decir N sera 4.

cont_modN.rar
« Última modificación: 07 de Noviembre de 2010, 20:26:38 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #8 en: 30 de Octubre de 2010, 19:30:32 »
Contador de Anillo.
Este se encarga de desplazar los bits en cierto sentido (Izquierdo o Derecho). A continuación se muestra el código necesario para lograr esto.

Código: [Seleccionar]
/*////////////////////////////////////////////////////////////////////////////////
Autor:  Luis Alberto Vargas Tijerino.
Alias:  Bigluis.
Pais:   Nicaragua.
Fecha:  30 de Octubre del 2010.  
*////////////////////////////////////////////////////////////////////////////////
module cont_despN #(
    parameter N=4)(
    input clk,
    input clr,
    output reg [N-1:0] Q
    );

always @(posedge clk or posedge clr)
  if(clr) Q <= 4'b0001;     //Si se Activa clr Q sera igual a 4'b0001
  else Q <= {Q[N-2:0],Q[N-1]};           //De lo contrario Q sera igual al valor de Q dezplazado un bit hacia la izquierda.

endmodule

Archivo del Proyecto

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:13:50 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #9 en: 03 de Noviembre de 2010, 17:53:42 »
Divisor de Reloj.
Muchas veces es necesario dividir la frecuencia de entrada a una frecuencia más baja, esto se hace porque muchos equipos no pueden trabajar a frecuencias muy altas, como es el caso de los display de 7 segmentos que se necesitan ser multiplexados en tiempo, si la frecuencia de multiplexasión es demasiado alta entonces no se podra mostrar nada en los display y por el contrario si es demasiado baja el usuario observaría como cada display se enciende uno por uno perdiendo la ilusion optica de que todos los display están encendidos a la vez.

El Kit de desarrollo Basys2 tiene 2 generadores de señal de relog integrados, uno de ellos es de 50MHz mientras que el otro es de 1Hz, por lo tanto no es posible utilizar ninguno de ellos para manejar los 4 display que posee el kit.

Para realizar un divisor de reloj simplemente se toman una de las salidas de un contador, a continuación se muestra el código para lograr esto.
Código: [Seleccionar]
/**********************************************************************************
Autor:    Luis Alberto Vargas Tijerino.
Alias:    Bigluis.
Fecha:   3-11-10
**********************************************************************************/

module clkdiv(
    input mclk,
    input clr,
    output clk190,
    output clk25
    );

reg [17:0] q;

//contador de 18-bit
always @(posedge mclk or posedge clr)
    if(clr) q <= 0;        //Si se activa clr el proximo valor de q sera 0
    else    q <= q + 1;    //de lo contrario el siguiente valor de q sera q+1
    
assign clk25  = q[0];    //50MHz/2^(0+1)=25MHz
assign clk190 = q[17];   //50MHz/2^(0+17)=190Hz    

endmodule
« Última modificación: 07 de Noviembre de 2010, 19:04:09 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #10 en: 06 de Noviembre de 2010, 20:54:49 »
Controlador de los Display de 7 segmentos Completos.

En este ejemplo se observa como se combinan la teoría de multiplexores y convertidores de código con la teoría de máquinas secuenciales.

Para controlar los cuatro display de forma separada es necesario multiplexarlos en el tiempo, es decir, encenderemos un display a la vez. Esto es posible si utilizamos un contador que controla las entradas de seleccion de un multiplexor cuadruple de 4 a 1, las entradas de datos son los códigos hexadecimales de cada display y las salidas del mux van al convertidor de hexadecimal a 7 segmentos que controlan los kátodos de los display. Por otro lado las salidas del contador van a un Decodificador de 2 a 4 que controla los anodos de los display. Esto se muestra en la figura siguiente.



A continuación se muestra el código para lograr esto.
Código: [Seleccionar]
// Autor:   Luis Alberto Vargas Tijerino.
// Fehca:   22:21:03 10/24/2010
// Nombre:  hex7seg
// Pais:    Nicaragua
module hex7seg(
   input clr,
   input clk,
   input [15:0] x,      //Declaramos el bus de entrada in
   output [6:0] a_to_g, //Declaramos el bus de salida a_to_g, para controlar los katodos.
   output [3:0] an      //Declaramos el bus de salida an, para controlar los andos.
   );

wire [3:0]in;  //Declaramos el bus auxiliar tipo wire de 4 bits in.
reg [1:0]sel;  //Declaramos el bus auxiliar tipo reg de 2 bits sel.

//Contador de corrida libre de 2 bits.
always @(posedge clk or posedge clr)   //Siempre que ocurra el flanco positivo de clk o clr.
   if(clr)sel<=0;    //Si se activa clr el siguiente valor de sel sera 0.
   else sel<=sel+1;  //De lo contrario el siguiente valor de sel sera sel+1.

//Multiplexor Quadruple de 4 entradas 1 salidas.
assign in=x[sel*4+:4]; //Si sel=2 entonces in=x[2*4+3+:4] o in=x[11:8].
                           //Por lo tanto se seleccionan las 4 entradas correspondientes al display a encender.

//Decodificador de 2 a 4. Selecciona el bit de salida correspondiente.
assign an=(sel==0)?4'b1110:   //Si sel es igual a 0 an sera igual a 4'b1110
          (sel==1)?4'b1101:   //Si sel es igual a 1 an sera igual a 4'b1101
          (sel==2)?4'b1011:   //Si sel es igual a 2 an sera igual a 4'b1011
                   4'b0111;   //Si sel es igual a 3 an sera igual a 4'b0111

//Tabla para realizar la conversion de hex a 7-seg.
assign a_to_g= (in==0)? 7'b000_0001:
               (in==1)? 7'b100_1111:
               (in==2)? 7'b001_0010:
               (in==3)? 7'b000_0110:
               (in==4)? 7'b100_1100:
               (in==5)? 7'b010_0100:
               (in==6)? 7'b010_0000:
               (in==7)? 7'b000_1111:
               (in==8)? 7'b000_0000:
               (in==9)? 7'b000_0100:
               (in=='hA)? 7'b000_1000:
               (in=='hB)? 7'b110_0000:
               (in=='hC)? 7'b011_0001:
               (in=='hD)? 7'b100_0010:
               (in=='hE)? 7'b011_0000:
                          7'b011_1000;

endmodule

Por aqui pueden descargar el archivo correspondiente al proyecto.

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:29:47 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #11 en: 13 de Noviembre de 2010, 05:28:12 »
Contador BCD
Los contadores BCD son contadores modulables de 0 a 9 que se conectan en cascada, estos se utilizan con el fin de evitar el convertidor Binario a BCD que sería necesario si utilizamos contadores simples.

A continuación se muestra el esquemático que utilizaremos como módulo superior para el contador. La función de este contador es mostrar en los display de 7 segmentos el contedo desde el 0 hasta el 9999. En el esquemático siguiente se observa que:
  • La entrada clk del primer contador se conecta a la entrada rcclk de frecuencia de 1Hz
  • La salida Q[3] del primer contador se conecta a la entrada clk del segundo contador
  • La salida Q[3] del segundo contador se conecta a la entrada clk del tercero contador
  • La salida Q[3] del tercero contador se conecta a la entrada clk del cuarto contador
  • Las salidas Q[3:0] de cada contador se conectan a las entradas de x[15:0] del convertidor de 7 segmentos mediante el Tap4x4_16 que agrupa sus 4 entradas de 4 bits y en una salida de 16 bits
  • La entrada clr de todos los módulos está conectada al btn[0]



A continuación se muestra el código del Tap4x4_16
Código: [Seleccionar]
module Tap4x4_16(
    input [3:0] x15_12,
    input [3:0] x11_8,
    input [3:0] x7_4,
    input [3:0] x3_0,
    output [15:0] x
    );

assign x={x15_12,x11_8,x7_4,x3_0};

endmodule

Y finalmente el código del Tap4_1w3 que toma en su salida el bit 3 de su entrada de 4 bits.
Código: [Seleccionar]
module Tap4_1w3(
    input [3:0] x,
    output x3
    );

assign x3=x[3];

endmodule


Por aquí pueden descargar el Proyecto

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:30:33 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #12 en: 18 de Noviembre de 2010, 13:11:01 »
Circuito Anti-Rebotes.
Existen muchos casos en los que es necesario conectar interruptores o botones a cualquier dispositivo digital para enviarle datos binario. Por lo general se comete el error de creer que los interruptores o botones pueden generar un cambio instantaneo, pero eso es falso, al realizar el cambio en estos dispositivos se produce una serie de rebotes generando así una serie de unos y ceros lógicos simultaneos y aleatorios, es decir no sabemos con exactitud cuantos 1 o cuantos 0 ha leído nuestro dispositivo digital, por lo tanto es necesario crear un circuito que elimine los rebotes a como se muestra en la siguiente figura.



A como se observa en el circuito de la parte central de la imagen anterior utiliza un capacitor para filtrar los rebotes producidos, esta opcion colleva a un gasto innecesario. En la siguiente opcion se muestra un circuito hecho a base de conpuertas lógicas, cosa que teóricamente podría ser modelado en nuestro FPGA pero en la práctica no es así ya que es imposible determinar el retardo producido por las compuertas internas del FPGA y en la mayoría de los casos durante el modelado el compilador determina que no existe una compuerta con mayor retardo que la otra, es por eso que los fabricantes proponen el siguiente circuito.



En el circuito anterior se utilizan 3 Flip-Flops D que se conectan en serie creando un registro de desplazamiento, por lo tanto cada vez que se activa la entrada inp por lo menos durante 3 ciclos de reloj entonces la salida outp se activará. Es recomendable que la entrada de reloj sea al rededor de 190Hz por lo cual utilizaremos el módulo clkdiv.

Ya que el kit BASYS2 solo posee 4 botones haremos un modulo que elimine el rebote para cuatro botones, a continuación se muestra el código correspondiente.
Código: [Seleccionar]
module debounce4(
   input [3:0] inp,     //Declaramos la entrada tipo bus de 4 bits inp
   input cclk,          //Declaramos la entrada clk
   input clr,           //Declaramos la entrada clr
   output [3:0] outp    //Declaramos la salida tipo bus de 4 bits outp
   );

reg [3:0] delay1;       //Declaramos la conexion auxiliar tipo reg delay1
reg [3:0] delay2;       //Declaramos la conexion auxiliar tipo reg delay2
reg [3:0] delay3;       //Declaramos la conexion auxiliar tipo reg delay3

always @(posedge cclk or posedge clr) begin
   if(clr) begin        //Si se activa clr
      delay1<=0;        //el siguiente valor de delay1 sera 0
      delay2<=0;        //el siguiente valor de delay2 sera 0
      delay3<=0;        //el siguiente valor de delay3 sera 0
   end
   else begin           //De lo contrario
      delay1<=inp;      //el siguiente valor de delay1 sera inp
      delay2<=delay1;   //el siguiente valor de delay2 sera delay1
      delay3<=delay2;   //el siguiente valor de delay3 sera delay2
   end
end

//Si la entrada inp es 1 durante 3 ciclos de cclk  outp sera 1.
assign outp = delay1 & delay2 & delay3;   //outp sera 1 si delay1, delay2 y delay3 son 1.

endmodule

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:39:14 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #13 en: 18 de Noviembre de 2010, 18:31:15 »
Generador de Pulso de Reloj.
Este módulo se caracteriza por generar un pulso de reloj limpio (sin rebotes) al activar un botón o un interruptor. A continuación se muestra el circuito que se encarga de realizar esto.



En la imagen anterior se puede observar que el circuito esta compuesto por tres Flip-Flops D conectados en cascada formando un registro de desplazamiento, similar al circuito del mensaje anterior. La salida outp se activará si la entrada inp se mantiene activa por lo menos durante 2 ciclos de reloj cclk, luego durante el tercer ciclo de reloj cclk la salida outp se desactivará aún cuando se mantenga activa la entrada inp

El código correspondiente a este circuito se muestra a continuación.
Código: [Seleccionar]
module clock_pulse(
   input inp,        //Declaramos la entrada inp
   input cclk,       //Declaramos la entrada cclk
   input clr,        //Declaramos la entrada
   output outp       //Declaramos la salida outp
   );

reg [2:0] delay;     //Declaramos el registro auxiliar de 3 bits delay

always @(posedge cclk or posedge clr)
   if(clr) delay<=0;                   //Si se activa clr el proximo valor de delay sera 0.
   else delay[2:0]<={delay[1:0],inp};  //de lo contrario el proximo valor de delay[2] sera delay[1]
                                       //el proximo valor de delay[1] sera delay[0] y
                                       //el proximo valor de delay[0] sera imp.
        
//Si imp permanece activo durante 2 ciclos de reloj outp se activara y en el siguente ciclo se desactivara
assign outp = delay[0] & delay[1] & ~delay[2];//outp sera 1 si delay[0] y delay[1] son 1 y delay[2] es 0.

endmodule

Comentarios
« Última modificación: 20 de Noviembre de 2010, 16:40:01 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Ejemplos Verilog
« Respuesta #14 en: 19 de Noviembre de 2010, 12:58:46 »
Máquinas de Estados Aleatorios.
A diferencia de las máquinas de Estados Secuenciales, como los contadores, este tipo de máquinas de Estados no sigue una secuencia lógica, por ejemplo: una máquina de estados que despues del estado 1 sigua el 3 y luego el 2 y finalmente regresa al 1 para iniciar de nuevo un ciclo. A continuación se muestra una figura que detalla el funcionamiento de esta máquina de estados.



A continuación se muestra el código para realizar esta máquina de Estados.
Código: [Seleccionar]
module maquinaestados(
    input clk,
    input clr,
    output [1:0] present_state
    );
reg [1:0] next_state;               //Declaramos la variable auxiliar next_state.
assign present_state=next_state;    //Declaramos que next_state se convertira en present_state.

always@(posedge clk or posedge clr) //Siempre que ocurra el flanco positivo de clk o clr.
   if(clr)next_state=0;             //Si se activa clr el proximo estado sera 0.
   else                             //De lo contrario
      case(present_state)           //En dependecia del estado presente.
         0:next_state=1;            //Si el estado presente es 0 el proximo Estado sera 1.
         1:next_state=3;            //Si el estado presente es 1 el proximo Estado sera 3.
         2:next_state=1;            //Si el estado presente es 2 el proximo Estado sera 1.
         3:next_state=2;            //Si el estado presente es 3 el proximo Estado sera 2.
         default:next_state=0;      //Por defecto el proximo estado sera 0.
      endcase

endmodule

A continuación se muestra la imagen de la simulación.


Comentarios
« Última modificación: 03 de Febrero de 2011, 13:10:04 por bigluis »
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA


 

anything