This manual was originally written in the Year 2014 by the Lecturer Holguer A. Becerra for the FPGA course of UPB 31289, and now republished and revised for FPGAlover by the same author.

 

Quartus Project:

Pre-Compiled Binaries(See QSF for Pin Connections):

LVDS Pinout of DE0-NANO(Download):

 

LVDS GPIOs on DE0-NANO      
GPIO FPGA LVDS(P/N) JP[N](PIN) BANK LVDS mode F_HSCLK Receiver(MHz) F_HSCLK Transmitter(MHz) HSIODR Mbps
GPIO_1_[1] PIN_T15 N 4 4 LVDS_E_3R - 320 640
GPIO_1_[2] PIN_T14 P 5 4 LVDS_E_3R - 320 640
GPIO_1_[3] PIN_T13 N 6 4 LVDS_E_3R - 320 640
GPIO_1_[4] PIN_R13 P 7 4 LVDS_E_3R - 320 640
GPIO_1_[5] PIN_T12 N 8 4 LVDS_E_3R - 320 640
GPIO_1_[6] PIN_R12 P 9 4 LVDS_E_3R - 320 640
GPIO_1_[7] PIN_T11 N 10 4 LVDS_E_3R - 320 640
GPIO_1_[9] PIN_R11 P 14 4 LVDS_E_3R - 320 640
GPIO_1_[16] PIN_L16 N 21 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[19] PIN_L15 P 24 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[17] PIN_K16 N 22 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[31] PIN_K15 P 38 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[18] PIN_R16 P 23 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[21] PIN_P16 N 26 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[22] PIN_R14 N 27 4 LVDS_E_3R - 320 640
GPIO_1_[25] PIN_P14 P 32 4 LVDS_E_3R - 320 640
GPIO_1_[23] PIN_N16 N 28 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_1_[24] PIN_N15 P 31 5 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
                 
                 
GPIO_0_[0] PIN_D3 P 2 8 LVDS_E_3R - 320 640
GPIO_0_[1] PIN_C3 N 4 8 LVDS_E_3R - 320 640
GPIO_0_[2] PIN_A2 N 5 8 LVDS_E_3R - 320 640
GPIO_0_[3] PIN_A3 P 6 8 LVDS_E_3R - 320 640
GPIO_0_[5] PIN_B4 P 8 8 LVDS_E_3R - 320 640
GPIO_0_[6] PIN_A4 N 9 8 LVDS_E_3R - 320 640
GPIO_0_[7] PIN_B5 P 10 8 LVDS_E_3R - 320 640
GPIO_0_[8] PIN_A5 N 13 8 LVDS_E_3R - 320 640
GPIO_0_[10] PIN_B6 P 15 8 LVDS_E_3R - 320 640
GPIO_0_[11] PIN_A6 N 16 8 LVDS_E_3R - 320 640
GPIO_0_[12] PIN_B7 P 17 8 LVDS_E_3R - 320 640
GPIO_0_[14] PIN_A7 N 19 8 LVDS_E_3R - 320 640
GPIO_0_[20] PIN_E8 N 25 8 LVDS_E_3R - 320 640
GPIO_0_[21] PIN_F8 P 26 8 LVDS_E_3R - 320 640
GPIO_0_[24] PIN_C9 N 31 7 LVDS_E_3R - 320 640
GPIO_0_[25] PIN_D9 P 32 7 LVDS_E_3R - 320 640
GPIO_0_[30] PIN_A12 N 37 7 LVDS_E_3R - 320 640
GPIO_0_[33] PIN_B12 P 40 7 LVDS_E_3R - 320 640
GPIO_0_[31] PIN_D11 N 38 7 LVDS_E_3R - 320 640
GPIO_0_[32] PIN_D12 P 39 7 LVDS_E_3R - 320 640
                 
GPIO_2_[2] PIN_C14 N 7 7 LVDS_E_3R - 320 640
GPIO_2_[7] PIN_D14 P 12 7 LVDS_E_3R - 320 640
GPIO_2_[3] PIN_C16 N 8 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_2_[4] PIN_C15 P 9 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_2_[8] PIN_F15 P 13 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_2_[9] PIN_F16 N 14 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_2_[11] PIN_G16 N 16 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640
GPIO_2_[12] PIN_G15 P 17 6 TRUE LVDS/LVDS_E_3R 420/- 420/320 840/640

Results:

 

 

Instructions (Read explanation before you proceed)

1. Obtain an HDMI cable and cut one end of it (These cut cable ends will be connected to the LVDS to TMDS translator).

2. Download the template and review where the LVDS channels are assigned(See .QSF) so that you can connect them to the LVDS to TMDS translator.

3. Once you have set up the external scheme for the FPGA, generate the .sof file, connect the HDMI cable to the display, and program the FPGA.

4. What appears on the screen? What resolution and frequency is it displaying? (You should see what is on the video results)

5. On line 46 of the template, modify the parameters, regenerate the .sof file, and verify each of the resolutions.

 

Relevant Documents 

  1. LVDS Owner’s Manual
  2. Video Connectivity Using TMDS I/O in Spartan-3A FPGAs
  3. Implementing a TMDS Video Interface in the Spartan-6 FPGA
  4. Double Data Rate I/O (ALTDDIO_IN, ALTDDIO_OUT, and ALTDDIO_BIDIR) Megafunctions
  5. KYANITE Schematic
  6. VESA TIMINGS
  7. Support HDMI 1.3 12-Bit Deep Color With the TMDS341A

 

Explanation

In this practice, we will understand HDMI (High Definition Multimedia Interface) video interface built for the DE0-NANO. To do this, we must understand how TMDS (Transition Minimized Differential Signaling) transmission works and develop a Verilog HDL transmission module capable of controlling this type of video interface using the DE0-NANO (Cyclone IV).

TMDS, or Transition Minimized Differential Signaling, shares similarities with LVDS (Low Voltage Differential Signaling). Both standards involve differential signaling for the input and output of HDMI connectors. However, they differ in terms of voltage parameters and operating ranges, including VIH (High-level input voltage), VIL (Low-level input voltage), VOH (High-level output voltage), and VOL (Low-level output voltage). It's important to note that TMDS is more closely related to Current Mode Logic (CML).", as seen in the following figure.

 

As shown in the figure, LVDS varies with voltage ranges between 1 and 1.4 V, with a swing of +-350mV and maximum transmission speeds of up to 3.125 Gbps, while CML transmission supports speeds of up to 10 Gbps with operating voltages ranging between 2.7V and 3.4 V and a swing of +-800mV. The following table illustrates the differences between LVDS and CML in terms of their configuration for reception and transmission, information you can read in the "LVDS Owner's Manual" by Texas Instruments.

 

Similar to CML, TMDS transmission has 50 Ohm pull-up resistors in its receivers and transmitters. Its input and output voltage parameters are also similar, as shown in the table below, which displays the operating ranges of TMDS and the conceptual scheme.

 

Why is it important to understand TMDS and its differences compared to LVDS?

Altera's Cyclone IV FPGAs do not yet have standards for handling TMDS-type signals. However, this doesn't mean that you can't design an HDMI transmission system. In this case, the Cyclone IV FPGA has LVDS differential channels that can be adapted to TMDS with either AC or DC coupling, as explained in the manual "Interfacing LVDS with other differential I/O types."

What does an HDMI transmitter look like?

An HDMI TX consists of 4 TMDS channels:

Channel 0: It is responsible for transmitting the blue video component and the VSYNC and HSYNC synchronization pulses, similar to what we saw in the VGA practice.

Channel 1: It is responsible for transmitting the green video component and some control commands and encoded audio.

Channel 2: It is responsible for transmitting the red video component and some control commands and encoded audio.

Clock channel: It is responsible for sending the base clock, which VSYNC and HSYNC rely on.

Note: All channels are encoded using the TMDS algorithm, which converts 8-bit video signals per color component into 10-bit encoded signals. The ninth bit is produced through something called "Transition Minimizing," and the tenth bit is produced to maintain an appropriate DC balance in relation to the number of zeros and ones generated after adding the ninth bit.





After the encoding stage of each channel, data serialization follows, where 10 bits must be transmitted per channel. These 10 bits can represent a video pixel, header, or audio sent through the TMDS channels, as shown in the following figure.

HDMI is composed of three TMDS operating modes:

  1. Video Data Period: When visible video is transmitted.
  2. Data Island Period: When video is not visible and is used to transmit audio and auxiliary data.
  3. Control Period: During this period, the necessary headers for transmitting audio and video are sent.


 

The TMDS clock signal is the pixel_clock signal generated in the original video synchronizer. Each of the 10 bits must be serialized within the period of this signal. This means that the serialization stage must operate with a clock 10 times faster than the pixel_clock.

For example:

  • To send a 800x600@60Hz SVGA video signal, assuming the pixel_clock is 40MHz, a clock of 400MHz would be needed to serialize the data properly.
  • To send a 1280x720@60Hz 720p video signal, assuming the pixel_clock is 74.25MHz, a clock of 742.5MHz would be required to serialize the data.

Note: The Cyclone IV in the DE0-NANO can generate signals up to 475MHz with its internal PLLs. However, this doesn't mean that you can't create an HDTV video interface for 720p or 1080i. There are other techniques, such as using DDIOs to generate double data rates, to achieve data transmission frequencies of up to 840Mbps using the Cyclone IV's LVDS channels.

In the following image designed by Xilinx Corp (modern FPGAs from this brand are compatible with TMDS standards and don't require coupling), you can observe an HDMI transmitter more closely. In the blue box, you can see the encoding stage, in the red box, the data synchronization stage, in the green box, the signal stage based on the original video clock signal, in the magenta box, the data serialization stage, and in the cyan box, the TMDS differential channels.

Just like when building the VGA synchronizer, the first thing we need to know is the HDMI connector, where:

  • Pins 1 and 3 are the channel 2 signals in TMDS.
  • Pins 7 and 9 are the channel 0 signals in TMDS.
  • Pins 4 and 6 are the channel 1 signals in TMDS.
  • Pins 10 and 12 are the clock channel signals in TMDS.
  • Pin 13 is the CEC (Consumer Electronics Control) used for sending control commands between devices.
  • Pins 15 and 16 are dedicated to DDC (Display Data Channel), used for EDID (Extended Display Identification Channel) communications that use the i2C protocol for information exchange between peripherals.
  • Pin 18 is an output that supplies low current at 5V.
  • Pin 19 is an input for detecting HDMI cable connection or disconnection.

In the following image, you can observe various boxes. The main box contains the description of the hardware that the Cyclone IV in the DE0-NANO will use for HDMI TX. External to the FPGA, there is additional hardware required to translate LVDS to TMDS, necessary to make LVDS mode compatible with HDMI's native TMDS.


 

The design within the Cyclone IV(DE0-NANO) includes:

  • Video Sync: Responsible for generating signals relative to video activation signals with their respective timing.
  • PLL: Responsible for generating the clock signal, maintaining phase, one controlling the video synchronizer, and another multiplying the reference signal of the video synchronizer PCLK (Pixel Clock Reference) by x5. All clock signals go to the FPGA's global clocks.
  • TMDS encoder: Encodes RGB, VSYNC, HSYNC, VDE, AUX, and ADE signals.
  • LVDS DRIVER: True LVDS I/O mode in the Cyclone IV.
  • DDIO: Double Data rate, responsible for sending data outputs at double the necessary frequency (see more).
  • Synchronizer: Data synchronizer between low-frequency and high-frequency clocks.
  • Serializer: 10:2 data serializer, serializing a bus of 10 bits two by two to send them to the DDIO, which is responsible for sending the data at double the speed in Mbps.


You will have as a foundation the Video Sync, the PLLs, the TMDS encoder, the DDIO, and a small serializer;

 

you should assemble circuit converter that appears in the image

Note: According to the LVDS Owner's Reference Manual from Texas Instruments, most CML/TMDS receivers have AC coupling at the input, which allows an LVDS output to be connected directly to HDMI inputs without the need for the previous circuit. So good news!, do it under your own risk, FPGAlover does not take any responsibility if you burn or damage your FPGA.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Written by Holguer Andres
 
Requires:

PSP Screen Video Using Nios II
PSP Screen Touch Stand Alone
PSP Screen Touch Using Nios II
PSP Screen Video and Touch Stand Alone
PSP Screen Examples
PSP Screen Pinout
PSP Screen Documents

 
 
Parte HW:
  1. Descargue la siguiente plantilla(Download this file (DE0_NANO_TFT_PSP.zip)DE0_NANO_TFT_PSP.zip) y descomprimala en una ruta sin espacios y corta.
  2. Revise las conexiones del pinout y haga las respectivas conexiones de la pantalla con la DE0-NANO.
    1. Ver LCD Datasheet.
    2. Ver Pinout.
  3. Ahora abra el proyecto Quartus y abra Qsys(Seleccione system.qsys).
  4. Una vez en Qsys, agregue el modulo llamado "Frame Reader" y configure de la siguiente manera: 
    1. El Frame Reader, leerá directamente de la RAM una sección de memoria con las características que están en el recuadro
  5. Ahora conecte el Frame reader de la siguiente manera: 
  6. Ahora agregue el modulo "Clocked Video Output" y configure de la siguiente forma:

     

  7. La razon por la cual se configura el "Clocked Video Output" de esta manera usted la puede encontrar en las paginas  63 y pagina 65 del Download this file (KT43B0E8257-40A (1).pdf)datasheet.
  8. Ahora conecte el modulo "Clocked Video Output" de la siguiente forma:
  9. Ahora se debe hacer un pequeño calculo matemático para seleccionar desde antes donde queremos guardar nuestro Frame de video, si queremos que no vaya a ver problemas con la memoria de heap o stack del sistema. El calculo es el siguiente, si queremos un frame de 480x272 que es la resolución que se quiere alcanzar en la pantalla, necesitamos saber ¿Cuanto espacio gasta esto en bytes?, lo cual se puede encontrar multplicando 480x272x4, donde el 4 significa que por cada pixel se gastaran 4 Bytes por color(un int).
    480x272x4=522240 Bytes=0x7f800 Bytes ==> si se quiere 1 Frame.
    480x272x4x2=1044480 Bytes=0xff000 Bytes==> si se quiere 2 Frame.
    En nuestro diseño dejaremos 2 Frames entonces necesitamos dejar un espacio destinado a Video del tamaño de 480x272x4x2=1044480 Bytes=0xff000 Bytes
  10. Ahora en el Qsys abra las opciones de la CPU y modifique "Exception Vector Offset" con el valor de 0xff000 + 0x20, los 32 Bytes de mas es por estandar que
    deben ser agregados al Exception Vector.

    Esto se hace para que el procesador se limite a trabajar desde este punto de partida, y no existan problemas de tener Video donde no debemos tenerlo.
  11. Ahora guarde los cambios y oprima en "Generate".
  12. En el Modulo Top de Quartus usted tiene instanciado en el Nios lo siguiente(Donde TFT_DCLK, proviene de un PLL y transporta un reloj de 9 MHz segun las  paginas 63 y pagina 65 del Download this file (HX8257.pdf)HX8257.pdf): 
 
Parte SW:
 
    1. Abra el Nios II Software Build y cree un nuevo proyecto(Nios II Application and BSP from Template) llamado "video_test".
    2. Descargue el siguiente archivo.zip(Download this file (video_test.zip)video_test.zip) y copie en el proyecto "video_test" los archivos que hay en el.
    3. Ahora haga "Clean Project" tanto de la carpeta de aplicación como de la de BSP.
    4. Genere el BSP.
    5. Build Project.
    6. Luego corra el proyecto con "Run As->Nios II Hardware"
    7. Una vez programe deberá tener sobre su pantalla la siguiente figura.
    8. Usted puede quitar el comentario de la linea 15 para tener Double Frame(Mientras dibuja en un frame muestra el otro).
    9. Si se da cuenta en la lineas 11 y 12 puede ver la ubicación en memoria de los Frames de 480x272 en la SDRAM.
    10. Para aumentar la velocidad de dibujo puede cambiar el Nios II a Fast o podría hacer acceleración por HW.
 

To use the TouchScreen of the Screen, we will be driving the chip XPT2046(Download this file (KT43B0E8257-40A (1).pdf)KT43B0E8257-40A (1).pdf), and it can be driven using the following Verilog Hardware Description, you can connect the pins of the screen wherever you want on the FPGA GPIO, and use it.

Download this file (4.3inch-480x272-Touch-LCD-B-Code.7z)Touch Driver Verilog Code Download

//TOUCHSCREEN
assign TFT_ADC_PENIRQ_N=GPIO_IN[0];
assign TFT_ADC_BUSY=GPIO_IN[1];
assign GPIO[0] =1'bz;
assign TFT_ADC_DOUT=GPIO[0] ;
assign GPIO[1]=TFT_ADC_DIN;
assign GPIO[2]=TFT_ADC_DCLK;		
assign GPIO[3]=TFT_ADC_CS_N;
wire	[11:0] 	x_coord;
wire	[11:0] 	y_coord;
reg	[11:0] 	x_coord_reg;
reg	[11:0] 	y_coord_reg;
wire			new_coord;	


//Touch
localparam X_ADC_UPPER_RIGTH=3975;
localparam X_POS_UPPER_RIGTH=479;
localparam X_ADC_LOWER_LEFT=112;
localparam X_POS_LOWER_LEFT=0;

localparam Y_ADC_UPPER_RIGTH=4032;
localparam Y_POS_UPPER_RIGTH=0;
localparam Y_ADC_LOWER_LEFT=110;
localparam Y_POS_LOWER_LEFT=271;

wire [11:0]  x_coord;
wire [11:0]  y_coord;
wire new_coord; 
 
adc_spi_controller u2 (
 .iCLK(CLOCK_50),
 .iRST_n(reset_n),
 .oADC_DIN(TFT_ADC_DIN),
 .oADC_DCLK(TFT_ADC_DCLK),
 .oADC_CS(TFT_ADC_CS_N),
 .iADC_DOUT(TFT_ADC_DOUT),
 .iADC_BUSY(TFT_ADC_BUSY),
 .iADC_PENIRQ_n(TFT_ADC_PENIRQ_N),
 .oX_COORD(x_coord),
 .oY_COORD(y_coord),
 .oNEW_COORD(new_coord),
  );
wire [31:0] numeratorX=(y_coord-X_ADC_LOWER_LEFT)*(X_POS_UPPER_RIGTH-X_POS_LOWER_LEFT);
wire [31:0] denominatorX=X_ADC_UPPER_RIGTH-X_ADC_LOWER_LEFT; 
reg [31:0] real_x;

wire [31:0] numeratorY=(x_coord-Y_ADC_LOWER_LEFT)*(Y_POS_LOWER_LEFT-Y_POS_UPPER_RIGTH);
wire [31:0] denominatorY=Y_ADC_UPPER_RIGTH-Y_ADC_LOWER_LEFT; 
reg[31:0] real_y;


always@(posedge CLOCK_50)
begin
 real_y<=real_y;
 real_x<=real_x;
 if(!TFT_ADC_PENIRQ_N && new_coord)
 begin
 real_y<= Y_POS_LOWER_LEFT-(numeratorY/denominatorY);
 real_x<= (numeratorX/denominatorX)+X_POS_LOWER_LEFT;
 end 
end​

On the Verilog code you will find that the Buses "real_x and real_y" are carring the coordingates where the touch screen is being pressed, and that the wire TFT_ADC_PENIRQ_N carries the interruption so you can determine when the screen was touched.

You can use this implementation, and wire it up to any soft processor, FSM, or logic you desire.

 

Enjoy!

 

Based on the Stand Alone Touch screen, now we can connect our nios II system using a simple PIO interface to the external touch screen driver, this to keep it simple, though you could create a custom hardware if that is what you want and you can do it by reading the article Nios II Custom Hardware - DE0-NANO-SOC.
 
For this implementation a Nios II is added on the decription using Qsys, and hooked up to a PIO of 21 bits, which carry the registers "the negated touch screen IRQ, real_x and real_y"
wire [20:0]touch_to_nios={~TFT_ADC_PENIRQ_N,real_x[9:0],real_y[9:0]};​

 

//
system u0 (
        .clk_clk              (sys_clk),              //           clk.clk
        .reset_reset_n        (reset_n),        //         reset.reset_n
		  .clk_io_clk                  (io_clk),                  //               clk_io.clk
        .reset_io_reset_n            (reset_n),   

			//EPCS		
        .epcs_sdo             (EPCS_ASDO),             //          epcs.sdo
        .epcs_data0           (EPCS_DATA0),           //              .data0
        .epcs_dclk            (EPCS_DCLK),            //              .dclk
        .epcs_sce             (EPCS_NCSO),             //              .sce
	
			//SDRAM
        .sdram_dqm            (DRAM_DQM),            //         sdram.dqm
        .sdram_ras_n          (DRAM_RAS_N),          //              .ras_n
        .sdram_cs_n           (DRAM_CS_N),           //              .cs_n
        .sdram_we_n           (DRAM_WE_N),           //              .we_n
        .sdram_dq             (DRAM_DQ),             //              .dq
        .sdram_cke            (DRAM_CKE),            //              .cke
        .sdram_addr           (DRAM_ADDR),           //              .addr
        .sdram_ba             (DRAM_BA),             //              .ba
        .sdram_cas_n          (DRAM_CAS_N),          //              .cas_n
		  
		  //Touch Screen
		  .touch_screen_export  (touch_to_nios[20:0]));
 
for the Nios II software you can use the following driver(Download this file (TOUCH_EVENT.h)TOUCH_EVENT.h Download this file (TOUCH_EVENT.c)TOUCH_EVENT.c) to use it on your Nios II designs or use it as guidance to port it over other soft core, and test it with the following main code.

/*
 * TOUCH_EVENT.c
 *
 *  Created on: 1/04/2014
 *      Author: Holguer A. Becerra
 *      This email address is being protected from spambots. You need JavaScript enabled to view it.
 */


#include <stdio.h>
#include <unistd.h>  // usleep (unix standard?)
#include "io.h" // I/O access
#include "system.h" // HAL system

#include "./touch_driver/TOUCH_EVENT.h"


int main(){


	// init Touch
	int result;
	int event=0;
	int pos_x,pos_y;



	while(1){
		event=event_is_up(&pos_x, &pos_y);
		  if(event==0){
			printf("Evento down x=%d y=%d\n",pos_x,pos_y);
		  }
		  else if(event==1){
			  printf("Evento UP x=%d y=%d\n",pos_x,pos_y);
		  }

		usleep(100000);
	}


	return 0;
}
 
 
You can download the full Quartus example by clicking on this link(Download this file (video_test.zip)TouchScreen Nios II.zip)
 
Enjoy!
 
 

So if you wondered, how one could use this as standalone, without Nios II, here the template and example.
 
If you go over the manual where it is explained all about VGA syynchronization, and if you read the datasheet of the screen, you realize the TFT Screen works exactly the same, just in a smaller scale than an standard VGA. so here the calculations if you want to modify or write a VGA synchronizer(Download this file (4.3inch-480x272-Touch-LCD-B-Code.7z)PSPVideoSync) for this particular TFT.
 
 
knowing that you need a 9MHz clock, you will need to instantiate a PLL to generate that frequency, so for that you need to open up the megawizard or ip catalog, and create 

 

 
 

 

 Once you have created the clock and as you have already the video sync verilog file, you can hook them up on the top file of your Quartus project. if you implemented the following example you will see on the TFT screen, a red background with a blue box drawn on the coordinates(x=10,y=55) with a width of 70 pixels, and height of 70 pixels.

//TFT
wire TFT_BACKLIGHT;//PWM
wire TFT_DSIP;
wire TFT_DCLK;
wire TFT_VSYNC;
wire TFT_HSYNC;
wire TFT_DE;
reg [7:0]TFT_RED;
reg [7:0]TFT_GREEN;
reg [7:0]TFT_BLUE;

///VGA
wire [10:0]CounterX;
wire [10:0]CounterY;


//TFT
assign GPIO[4]=TFT_BACKLIGHT;
assign GPIO[29]=TFT_DSIP;
assign GPIO[31]=TFT_DCLK;
assign GPIO[33]=TFT_DE;

assign GPIO[32]=TFT_HSYNC;
assign GPIO[30]=TFT_VSYNC; 

//TFT Colors
assign GPIO[12:5]=TFT_RED[7:0];
assign GPIO[20:13]=TFT_GREEN[7:0];
assign GPIO[28:21]=TFT_BLUE[7:0];


//TFT ON
assign TFT_DSIP=1'b1;
assign TFT_BACKLIGHT=1'b1;

//////////////////PLL VGA /////////////

pll_9MHZ	pll_9MHZ_inst (
	.inclk0 ( CLOCK_50 ),
	.c0 ( TFT_DCLK )// RELOJ 9MHZ
	);


////////////////// SINCRONIZADOR VGA ////////////

mi_vga mi_vga_inst
(
	.clk(TFT_DCLK) ,	// input  clk_sig
	.h_sync(TFT_HSYNC) ,	// output  h_sync_sig
	.v_sync(TFT_VSYNC) ,	// output  v_sync_sig
	.video_on(TFT_DE) ,	// output  video_on_sig
	.pixel_x(CounterX) ,	// output [N-1:0] pixel_x_sig
	.pixel_y(CounterY) 	// output [N-1:0] pixel_y_sig
);


wire square_on= (CounterX > 11'd10) && (CounterX < 11'd80) &&(CounterY > 11'd55) && (CounterY < 11'd125);

/////MUX DE VIDEO ////
always@(negedge TFT_DCLK)
begin 
   if(!TFT_DE)
	begin
	     TFT_RED<=8'h00;
		  TFT_GREEN <=8'd0;
		  TFT_BLUE <=8'd0;
	end
	else
	begin
	     TFT_RED<=8'hFF;
		 TFT_GREEN<=8'h00;
		 TFT_BLUE <=8'h00;
		 if(square_on)
		 begin
			TFT_RED<=8'h00;
		 	TFT_GREEN<=8'h00;
			TFT_BLUE <=8'hFF;
		 end
   	end
end


 

GUI on TFT using Only Verilog

So let's say now you wanted to implement a GUI using only Verilog, and taking advantage that you have access to a touch screen as well. Imagine you need to create a GUI of three buttons, which we could simply describe as boxes, as it is shown in the following image.

 

Once you have drawn these 3 boxes on the screen, you could now bind them to a touch screen action, using the stand alone touch screen module given in the section stand alone touch screen

 

after instantiating the touch screen verilog module on your top module, you can use "real_x, and real_y" to know the position where the screen is being touched, and the PENIRQ to determine if the screen is pressed. The above instantiation, has a new output named "PEN_DOWN", which is simply a delayed or anti bouncer representation of TFT_ADC_PENIRQ_N, which is useful to avoid bouncing.

You can download this modified touched driver here Download this file (touch.v)touch.v

To correlate the position of the touchscreen and the drawn boxes, you can simple add the condition using the buses "real_x, and real_y" in the following way

wire box_on= (CounterX > 11'd300) && (CounterX < 11'd400) &&(CounterY > 11'd100) && (CounterY < 11'd200);
wire box_on1= (CounterX > 11'd0) && (CounterX < 11'd100) &&(CounterY > 11'd0) && (CounterY < 11'd80);
wire box_on2= (CounterX > 11'd150) && (CounterX < 11'd250) &&(CounterY > 11'd50) && (CounterY < 11'd100);

wire box_oprimido=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd300) & (real_x[31:0]<11'd400) &   (real_y[31:0]>11'd100) & (real_y[31:0]<11'd200));
wire [23:0]color_box=box_oprimido?24'h00ff00:24'h0000ff;

wire box_oprimido_1=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd0) & (real_x[31:0]<11'd100) &   (real_y[31:0]>11'd0)   & (real_y[31:0]<11'd80));
wire [23:0]color_box_1=box_oprimido_1?24'h0000ff:24'h00ff00;

wire box_oprimido_2=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd150) & (real_x[31:0]<11'd250) & (real_y[31:0]>11'd50)  & (real_y[31:0]<11'd100));
wire [23:0]color_box_2=box_oprimido_2?24'h000000:24'hf00ff0;

So the wire "box_oprimido" carries the condition if the touchscreen is being pressed, the real_x is greater than the position 300 and less than 400, and the real_y is greater than the position 100 and less than 200, this wire will be set to 1. So for our logic this means that the "box_on" has been pressed by the user.

You can also use this wire to act  the input of a color multiplexer, so if you want to change the color of the box when you press the button, you can.

Here the modified code to make this example work.

Note: You need to add to the PLL a clock of 2KHz to make sure the touch screen driver works accordingly for the antibouncer(PEN_DOWN)

//TOUCHSCREEN 
wire TFT_ADC_BUSY;
wire TFT_ADC_PENIRQ_N;
wire TFT_ADC_DOUT;
wire TFT_ADC_DIN;
wire TFT_ADC_DCLK;
wire TFT_ADC_CS_N;


wire [31:0]  real_x; 
wire [31:0]  real_y;

wire PEN_DOWN;


//TFT
wire TFT_BACKLIGHT;//PWM
wire TFT_DSIP;
wire TFT_DCLK;
wire TFT_VSYNC;
wire TFT_HSYNC;
wire TFT_DE;
reg [7:0]TFT_RED;
reg [7:0]TFT_GREEN;
reg [7:0]TFT_BLUE;

///VGA
wire [10:0]CounterX;
wire [10:0]CounterY;


//TOUCHSCREEN
assign TFT_ADC_PENIRQ_N=GPIO_IN[0];
assign TFT_ADC_BUSY=GPIO_IN[1];
assign TFT_ADC_DOUT=GPIO[0] ;
assign GPIO[1]=TFT_ADC_DIN;
assign GPIO[2]=TFT_ADC_DCLK;		
assign GPIO[3]=TFT_ADC_CS_N;

//TFT
assign GPIO[4]=TFT_BACKLIGHT;
assign GPIO[29]=TFT_DSIP;
assign GPIO[31]=TFT_DCLK;
assign GPIO[33]=TFT_DE;

assign GPIO[32]=TFT_HSYNC;
assign GPIO[30]=TFT_VSYNC; 

//TFT Colors
assign GPIO[12:5]=TFT_RED[7:0];
assign GPIO[20:13]=TFT_GREEN[7:0];
assign GPIO[28:21]=TFT_BLUE[7:0];


//TFT ON
assign TFT_DSIP=1'b1;
assign TFT_BACKLIGHT=1'b1;

wire reset_n=1'b1;

//////////////////PLL VGA /////////////

pll_9MHZ	pll_9MHZ_inst (
	.inclk0 ( CLOCK_50 ),
	.c0 ( TFT_DCLK ),// RELOJ 9MHZ
	.c1(CLK_2KHz) //anti bouncer clock
	);


////////////////// SINCRONIZADOR VGA ////////////

mi_vga mi_vga_inst
(
	.clk(TFT_DCLK) ,	// input  clk_sig
	.h_sync(TFT_HSYNC) ,	// output  h_sync_sig
	.v_sync(TFT_VSYNC) ,	// output  v_sync_sig
	.video_on(TFT_DE) ,	// output  video_on_sig
	.pixel_x(CounterX) ,	// output [N-1:0] pixel_x_sig
	.pixel_y(CounterY) 	// output [N-1:0] pixel_y_sig
);

///////////////// TOUCH ///////////////////

touch touch_inst
(
	.CLOCK_50(CLOCK_50) ,	// input  CLOCK_50_sig
	.reset_n(reset_n) ,	// input  reset_n_sig
	.TFT_ADC_DIN(TFT_ADC_DIN) ,	// output  TFT_ADC_DIN_sig
	.TFT_ADC_DCLK(TFT_ADC_DCLK) ,	// output  TFT_ADC_DCLK_sig
	.TFT_ADC_CS_N(TFT_ADC_CS_N) ,	// output  TFT_ADC_CS_N_sig
	.TFT_ADC_DOUT(TFT_ADC_DOUT) ,	// input  TFT_ADC_DOUT_sig
	.TFT_ADC_BUSY(TFT_ADC_BUSY) ,	// input  TFT_ADC_BUSY_sig
	.TFT_ADC_PENIRQ_N(TFT_ADC_PENIRQ_N) ,	// input  TFT_ADC_PENIRQ_N_sig
	.real_x(real_x) ,	// output [31:0] real_x_sig
	.real_y(real_y) ,	// output [31:0] real_y_sig
	.CLK_2KHz(CLK_2KHz) ,	// input  CLK_2KHz_sig
	.PEN_DOWN(PEN_DOWN) 	// output  PEN_DOWN_sig
);

assign LED[0]=TFT_ADC_PENIRQ_N;
assign LED[1]=PEN_DOWN;


/// GUI logic
wire box_on= (CounterX > 11'd300) && (CounterX < 11'd400) &&(CounterY > 11'd100) && (CounterY < 11'd200);
wire box_on1= (CounterX > 11'd0) && (CounterX < 11'd100) &&(CounterY > 11'd0) && (CounterY < 11'd80);
wire box_on2= (CounterX > 11'd150) && (CounterX < 11'd250) &&(CounterY > 11'd50) && (CounterY < 11'd100);

wire box_oprimido=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd300) & (real_x[31:0]<11'd400) &   (real_y[31:0]>11'd100) & (real_y[31:0]<11'd200));
wire [23:0]color_box=box_oprimido?24'h00ff00:24'h0000ff;

wire box_oprimido_1=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd0) & (real_x[31:0]<11'd100) &   (real_y[31:0]>11'd0)   & (real_y[31:0]<11'd80));
wire [23:0]color_box_1=box_oprimido_1?24'h0000ff:24'h00ff00;

wire box_oprimido_2=((PEN_DOWN==1'b0) & (real_x[31:0]>11'd150) & (real_x[31:0]<11'd250) & (real_y[31:0]>11'd50)  & (real_y[31:0]<11'd100));
wire [23:0]color_box_2=box_oprimido_2?24'h000000:24'hf00ff0;

/////MUX DE VIDEO ////
always@(negedge TFT_DCLK)
begin 
   if(!TFT_DE)
	begin
	     TFT_RED[7:0]<=8'h00;
		 TFT_GREEN[7:0] <=8'd0;
		 TFT_BLUE[7:0] <=8'd0;
	end
	else
	begin
	     {TFT_RED[7:0],TFT_GREEN[7:0],TFT_BLUE[7:0]}<={8'hFF,8'h00,8'h00};
		 if(box_on)
		 begin
			{TFT_RED[7:0],TFT_GREEN[7:0],TFT_BLUE[7:0]}<=color_box[23:0];
		 end
		 else if(box_on1)
		 begin
			{TFT_RED[7:0],TFT_GREEN[7:0],TFT_BLUE[7:0]}<=color_box_1[23:0];
		 end
		 else if(box_on2)
		 begin
			{TFT_RED[7:0],TFT_GREEN[7:0],TFT_BLUE[7:0]}<=color_box_2[23:0];
		 end
   	end
end


 

 Then the results will be what is shown in the video below

 

 

You can download the template or example if you want from here: Download this file (DE0_NANO_TFT_GUI_VERILOG.qar)DE0_NANO_TFT_GUI_VERILOG.qar

Some examples you can download and use to verify your connections with your DE0-NANO
  • Test Video With PCEngine(.sof) & Pinout(GPIO_1[27]=AUDIO_L; assign GPIO_1[29]=AUDIO_R).
    • Utilizando el control panel de la DE0-NANO(Download this file (DE0_Nano_ControlPanel_V1.4.0.zip)DE0_Nano_ControlPanel_V1.4.0.zip), programe la EPCS desde la posición 0x7d000 con el archivo siguiente(.pce): JackieChan.pce
      • Open Control panel, once opened, click on Memory, then on Memory type list select "EPCS", select the check "File Length", on the address of section Sequential Write  type "07d000" and then click on the button write file to memory.
      • Select the file  JackieChan.pce, and OK.
      • Then wait until the EPCS is written.



      • Note: if it does not let you write, first click on Erase "Chip Erase (70 sec)"
    • Luego programe el .sof, ponga los SW[3:1] en la posición 3'b011 y oprima el KEY[0] para ver en funcionamiento el juego sobre su pantalla.
        
 
Enjoy!

 
 
PIN NO. SYMBOL DESCRIPTION TYPE FUNCTION
1 IRQ Touch screen interrupt output Low level while the touch screen detects pressing
2 5V 5V power supply input 5V power supply
3 MOSI Touch screen SPI data input input Connects to SPI MOSI
4 MISO Touch screen SPI data output output Connects to SPI MISO
5 SCK Touch screen SPI clock input Connects to SPI SCK
6 SSEL Touch screen chip select input Low active
7 PWM Backlight brightness adjustment input Control the backlight brightness via PWM
8 GND Ground input GND
9 BUSY Touch screen busy output  
10 NC      
11 R0 Data pin input Red data
12 R1
13 R2
14 R3
15 R4
16 R5
17 R6
18 R7
19 G0 Data pin input Green data
20 G1
21 G2
22 G3
23 G4
24 G5
25 G6
26 G7
27 B0 Data pin input Blue data
28 B1
29 B2
30 B3
31 B4
32 B5
33 B6
34 B7
35 DCLK LCD clock input LCD clock signal
36 DSIP NC    
37 HSYNC Horizontal Synchronization input Horizontal synchronous signal input
38 VSYNC Vertical Synchronization input Vertical synchronous signal input
39 DE Control mode selection input DE = 0 : SYNC mode
DE = 1 : DE mode
40 GND Ground input GND

 

 

 

 

 

Author:  Edgar Rodrigo Mancipe Toloza

 

Downloadables: 

 

ABSTRACT: The main objective of this paper is to present the steps of how to program a PID controller in a FPGA, and in that way to control a DC motor using Pulse Width Modulation. Also we want to give some ideas to people interested in program embedded controllers in hardware.

During the project we will use some tools to help us to visualize the behavior of the controller on the computer screen through rs232 communication and LabView chart to plot, and LCD display for visualize the Set Point, gains and the current value.

 

KEYWORDS: PID, Control, FPGA, DE0-Nano, Embedded.

 

INTRODUCTION

 

Nowadays FPGA's have increased their popularity due the many ways to acquire it, reliability, and low costs. As a consequence of that, we can see more FPGA's applications in control systems.

For many years, microcontrollers used to be on the top of this field due their low-cost, but through years FPGA's have turned into a striking option, thanks to its main property of controlling many systems in parallel in the same embedded system.[1]. 

In this project we want to show in a quick way, how to program a PID control in FPGA using Verilog language, also we will change the values of Gain variables to see the behavior of the controlled value.

This article is not intended to give a definitive PID algorithm, the intention is to introduce and give some ideas for the readers of how to create and implement their own PID equation embedded in FPGA.

 

 MATERIALS 

This section will show the name of the main objects used in the analog and digital interface of the project for signal conditioning and power circuit.

  • DE0-NANO BOARD: The development board selected for this Project is the DE0-Nano, which contains the following characteristics: [2]
    • Altera FPGA Cyclone IV EP4CE22F17C6
    • Analog-to-digital converter ADC128S022
    • Configuration device EPCS16 for non-volatile data storage
    • 4 dip-switch
    • 2 push buttons
    • 8 LED's

      Figure 1. DE0-Nano Board.

  • GEARMOTOR: The gearmotor selected have the next characteristics:

    • Torque 18Kg*cm
    • 80RPM
    • Power supply 12Vdc
      • Quadrature encoder of 8384 pulses per round 3v.




        Figure 2. Gearmotor. [3]



  • DISPLAY HD44780 2x16:  Monochromatic display 2X16 that will be use to visualize de set-point, current variable, proportional, integral and derivative gain

    Figure 3. LCD 2x16. [4]

  • H BRIDGE: the control circuit and power circuit, a L293D H Bridge is the selected option, so in that way the control circuit send digital signals to the chip for select the rotation of the motor. [5]

    Figure 4. L293D Block Diagram.

  • SERIAL-TO-USB CONVERTER:  For visualize the behavior of the variables in the computer screen, we decided to use a serial-to-usb FTDI FT232RL converter. So through a serial RS232 algorithm coming from the embedded we can send the information of the data's. [6]

    Figure 5. Serial-to-USB converter FT232RL.

 

BLOCK  DIAGRAM OF THE CONTROLLER

Before start to program the FPGA, is necessary defining a strategy through a block diagram. In the Figure 6, we can see that the Set Point is selected using a Dip- switch and the feedback signal is coming from the quadrature encoder coupled to the DC motor. The error is the difference between Set Point and feedback (Encoder), and the error sign defines the rotation of the motor through the H Bridge. A Pulse Width Modulation (PWM) is the output signal of the PID algorithm that will change its Duty Cycle depending of the controller result.

 

Figure 6 Block Diagram of the controller.

 

PROGRAMMING

Once defined the strategy for the controller, we proceed to program the algorithm in HDL Verilog, using Quartus II. In this case we divided the entire Project in different sub-modules that will allow us to interpret and design in modular way, so that is going to be an advantage at the moment of write and understand the program lines

 

  • SET POINT:
    For the Set Point there are 5 predefined positions that will be selected through a dip-switch. Due that the encoder coupled to the gearmotor generates 8384 pulses per round is necessary to calculate the value for each position



    Once we have the number of pulses for each position of the motor we proceed to program the set point selector, the next image will show the SP program:


    Algorithm for the Set Point.

  • CURRENT VALUE

    For know the value of the current value is necessary to read and interpret the data received by the encoder coupled to the DC motor. So in that case we use a circuit that will allow us to interpret the 2 quadratures signals into a counter that increment and decrement its value depending of the rotation of the encoder. [7]

    Figure 8. Quadrature decoder coupler circuit.

     

    In the figure 8 we can see that the count direction will determine if the counter will ascend or descend, also the count enable will be the clock pulse that determines the moment to calculate.

    The interpretation of this circuit in Verilog is shown in Figure 9.

    Figure 9. Verilog algorithm for quadrature decoder coupler circuit.

  • ERROR SIGNAL

    The error signal is calculated with the difference between Set Point and Feedback as we can see in algorithm shown in the figure 10.

    Figure 10. Verilog algorithm for error.

    But it's important to take note that when the feedback value is bigger than set-point value, it will be a negative saturation so it's necessary to identify when this happen with a signed bit, also put a condition if the signed bit tells that the value it's negative, do a two's complement. The next figure shows a possible way to do that: [8]

    Verilog algorithm for two's complement.

  • CONTROL

    Before start to write the control algorithm was necessary to define the expression to use, in this case we consulted the incremental PID algorithm as shown in the next equation: [9]

    After that we proceed to program the equation using a Finite State Machine (FSM) using each state for doing a operation, and add and substract at the end, as shown in the next figure:

    Figure 12. Verilog algorithm for PID controller

    Another important aspect to have in account is the anti-windup, due the abrupt change of the set point, the control signal can saturate into a max value or a min value (0-64000 on this case), in order to avoid that, an anti- windup algorithm is necessary, a possible way to describe that algorithm is shown in the next figure:


    Figure 13. Verilog algorithm for Anti-windup

  • PWM

    As we saw in figure 6, a PWM signal is going to be associated to the controller, so the duty cycle of the signal will change according to the value of m(k) that is the result of the PID equation. Before writing an algorithm for a PWM signal, it's necessary to think on how it works for an analog PMW circuit, a voltage comparator between a DC voltage level and a ramp wave, as we can see in the figure 14.

    Figure 14. Voltage comparator.

    Using that concept, an algorithm is written with a counter as a ramp wave, and the DC level will be the output of the control equation, giving as a result a PWM.

    Figure 15. PWM algorithm.

  • ROTATION

    The rotation is given by the signal bit coming from the error acquisition, depending of this value the PWM signal will be assigned to one of the two controls pins of the H Bridge. A hysteresis is added when the error is close to zero in order to avoid oscillations.

    Figure 16. Rotation algorithm

 

IMPLEMENTATION

On this stage we will present a test of the algorithm performance using labview and RS232 communication to send the data to the pc. Due that the importance of this document it's to present the controller, we are not going to focus in the RS232 algorithm that is also embedded in the FPGA. Another document will present the steps of how to use and program a serial-USB converter FT232.

 

  • TEST 1

    Parameters:

    • Input: Step
    • Set Point: 180° Set Point: 180
    • Kp=5
    • Ki=0
    • Kd=0

    In figure 17 we can see a higher position error, when Ki is 0, and Kp is very low.

    Figure 17. Response of test 1.

  • TEST 2

    When we raise Kp, we get closer to the desired value (180°), also the controller is faster, but is not the set point reached yet, is shown in figure 18.

    Parameters:

    • Input: Step
    • Set Point: 180° Set Point: 180
    • Kp=10
    • Ki=0
    • Kd=0.



      Figure 18. Response of test 2.

  • TEST 3

    Parameters:

    • Input: Step
    • Set Point: 180° Set Point: 180
    • Kp=5
    • Ki=3
    • Kd=0

Now we decrease Kp to 5 again, but this time Kp have a different value than 0. In figure 19 we can see that the response tents to reach the set point value slowly but with a small amount of overshoot (less than 5%).

Figure 19. Response of test 3.

 

  • TEST 4

    Parameters:

    • Input: Step
    • Set Point: 180° Set Point: 180
    • Kp=10
    • Ki=3
    • Kd=0

Increasing the Kp value will make the response faster, but also will increase the overshoot, as shown in figure 20.

Figure 20. Response of test 4.

  • TEST 5

    Parameters:

    • Input: Step
    • Set Point: 180° Set Point: 180
    • Kp=10
    • Ki=17
    • Kd=0

In this case we can see that increasing the Ki value to high, will make oscillate the system before stabilize, figure 21 is the result of the test 5.

Figure 21. Response of test 5.

ASSEMBLY IMAGES

 

Figure 22. Complete project.

 

LCD with Current Variable, Set-Point, Proportional Gain, Integral Gain and Derivative Gain values.

 

Figure 24. Serial-USB converter.

 

CONCLUSION

 

In this project we saw that is viable the implementation of a PID controller in a FPGA, and the modular design allow us to think and solve one problem at once. Trough the test made to the controller we manage to saw the behavior of the controlled variable when we change the values of the proportional an integral gains, as we saw, the proportional gain will give more speed to the controller but it also can increase the overshoot percent, in other way the integral gain can give a more accurate response getting closer to the set-point. There were also a test changing the derivative gain, however the response was always saturated because of the noise derived, so still pending the implementation of an additional filter to solve this problem

 

VIDEO DEMOSTRATION

 

REFERENCES

 

 

Written by Sherneyko Plata Rangel

Introducción:

El procesamiento digital de señales, y en este 
caso, el de audio, es una tarea exigente en cuanto a
recursos y velocidad,desde sus inicios se han usado 
integrados especializados para esta tarea, sin embargo 
con los avances de las ultimas décadas dispositivos
programables han  adquirido las capacidades para 
realizar  estos procesos, entre ellos se  encuentra la  
FPGA, que por sus capacidades y estructura pueden ser
configuradas para realizar tareas de forma similar a los 
asic,debido a esto y a su paralelismo, se han hecho muy
populares en este campo. 
Describir la lógica para este procesamiento puede llegar 
a ser tedioso  sobre todo si el numero de bloques, 
funciones y el orden de las mismas es alto, sin embargo
existen herramientas con la capacidad de generar un 
código hdl en base a un diagrama de bloques que ilustra 
de forma simplificada  las tareas a realizar sobre los 
datos,facilitando asi su  implementación,  y permitiendo 
que el diseñador se concentre mas en el diagrama
teorico y no en su traducción a HDL.En este proyecto se
implementa un generador de efecto basado en simulink 
y generador de código HDL.
 
 
Propuesta:

Mediante  simulink, realizar un procesamiento digital de señales que tome una señal de audio de entrada mediante un adc, genere los efectos sobre esta y  la convierta de nuevo al mundo analógico con un dac, todo esto usando una tarjeta de dispositivos diseñada para la tarjeta de desarrollo DE0-NANO. Hay que tener en cuenta las imperfecciones del código generado por simulink, cuya lógica es correcta pero no es confiable, generando dispositivos indeseados como latches en el compilador de la fpga.
 
 
Diagrama de bloques:



Etapas:

-Diseño del PCB de la tarjeta de dispositivos en 
-Eagle pcb
-Descripcion de los modulos ADC y DAC
-Diseño del blockset
-Traduccion del blockset
-Revision del código hdl generado (confiabilidad)
-Pruebas
 
Efectos:
Delay
Reverb
 
Archivos del proyecto y Paper Final:

Paper haz clic aquí.
 
 
 
 
Video:


 
 
 
Nota: El software utilizado en este proyecto fue usado con fines académicos para la materia de "Diseño Avanzado de Hardware - UPB Bucaramanga" y con la version DEMO de 30 dias ofrecida por Mathworks.
 
Nota2: En vez de usar un DAC externo para este proyecto se podria utilizar un modulo HDL de Modulacion Delta Sigma como el siguiente -- Haz clic Aquí