Written by Holguer Andres

 

In this manual you are going to understand how the N64 Controller works, and how we can acquire through a simple Finite State Machine (FSM), all the buttons states from the N64 controller using the DE0-NANO (you can use any FPGA board, and implement this manual).

it is important to make clear that this manual is based on http://larsivar.com/wp/?p=86 manual in which it is explained the N64 controller protocol, there is a software example for acquiring the buttons states. However in this example, the given AVR driver is ported to a simple Verilog Module, which can be simply instantiated as many times as the user desire without affecting any performance, taking advantage of the FPGA parallelism.

Required Materials:

  1. Any FPGA board (Though for this manual we are going to use the DE0-NANO).
  2. N64 Controller(18 CADs on Amazon).

 Brief Explanation:

  • Let's start by looking at the N64 contoller Pinout:


    As you can see on the image, the N64 controller interface has only 3 pins of which only one(Data) is used to drive the controller.

  • Now let's try to understand how we can obtain the n64 buttons states through the Data pin. The first thing we should know it is that this pin behaves as a bidirectional pin, and the N64 plays the roll of a slave that we must command with a Master Module, therefore we are going to drive the controller through a Master module that will be in charge of sending data to the controller, and vise versa. To have a better panorama about this scheme, you can take a look at the following image.


  • It is important to know that for getting the states of the N64 buttons, the Master module must send 9 bits. The first bit corresponds to a starting flag (Wakes up indicating that a command will be sent), and the next 8 bits correspond to a command(which tells the controller what data we are inquiring). Then after we send the first 9 bits through the DATA signal, the controller will answer with 34 bits.


  • Therefore, while the first nine bits are being sent the OE must be set to '1' to tell the bidirectional buffer and the controller we are sending data, and once these 9 bits are sent, the N64 will send the 34 bits as answer, hence, the OE shall be connected to '0' in order to capture the incoming data.

  • Timing is very important to talk to the N64 Controller, otherwise the controller is not going respond properly according to the already mentioned description. Thus, there are timing control we must have at the moment of sending the output signal (Zero flag and the 8 bits). Furthermore, the Verilog Module was designed to work at 50MHz, which it is vital to take into account when designing the FSM to generate the control signal.
    • There are two kind of signals we can send to the controller through the FSM, or we can receive from the N64 controller, these signal can be either 'Zero' or 'One'
      • Sending a '0':
      • Sending a '1':

    • As it could be observed on the previous images, for sending '0' the low signal remains longer (3us) whereas for sending '1' the lower signal remains just 1us.

  • Now it is time to put into words, and detail the behaviour of the first nine bits that have to be sent to the controller.
    • Initially the OE is assumed to be connected to '0'.
    • Then the OE is set to '1'.
    • Then the first bit or the flag has to be sent, this flag corresponds to a Zero.
    • Now the next 8 bits have to be sent, and the command to tell the controller ''Hey give me the buttons states!!" is 8'b00000011, as you can see in the following signal representation.

      Open in a new window to magnify
    • Once the the 9 bits have been sent, the FSM has to wait until the N64 controller has replied with 34 bits (in this case we are only interested in the first 33 bits, so we can get rid of the 34th bit, which only contains the stop bit)
    • After the N64 controller has sent the pulses indicating the different states of the buttons, the FSM has to wait for 100ms to give time to the controller, subsequently to send a finish signal.

 

  • Here the complete signal specs.

  • Once the logical procedure is understood, the following step is to put this into a FSM Diagram to make it more understandable.


    The previous FSM diagram is composed by 8 different states which are necessary to generate the control signal('9 bits'), and to wait for the N64 response.
    • IDLE: In this state the FSM only goes to the "POLL_STATE", and polling_data is set to zero when a start signal is given, this start signal is simply an input pin described in Verilog.
    • POLL_FSM: In this state the FSM has three different branches
      • if counter_polling is less or equal to 8 and the polling_data[counter_polling ] is zero, the states goes to SEND0_FSM1, and a delay counter is set to 3us.
      • if counter_polling is less or equal to 8 and the polling_data[counter_polling ] is one, the states goes to SEND1_FSM1, and a delay counter is set to 1us.
      • if counter_polling is greater than 8, the states goes to GET_FSM.

        It is important to know that the "polling_data" is just a bus of 9 bits connected to 9'b110000000, and the counter_polling is set to zero by the IDLE state. So if the polling_data is 0 the signal is going to be sent to the controller is a 0, which corresponds to maintain the output set to 0 for 3 us and then 1us to 1.
    • SEND0_FSM1: in this state, there is countdown of the register "delay" which corresponds to the number of pulses of 50 MHz required to wait for 3 us (150 pulses), once the register reaches 0, the state goes to the next State SEND0_FSM2.
    • SEND1_FSM1: in this state, there is countdown of the register "delay" which corresponds to the number of pulses of 50 MHz required to wait for 1 us(50 pulses), once the register reaches 0, the state goes to the next State SEND1_FSM2.
    • SEND0_FSM2, and SEND1_FSM2: Same as their predecessors, then go back to "POLL_FSM", the delay counter is set to 400000 pulses or 100 ms.
    • GET_FSM: In this state the FSM waits until an external logic to the FSM counts the number of falling pulses and rising pulses (sync), determines whether the incoming signal is '0' or '1', and stores the captured signal into a shift register.
    • FINISH: in this state, there is a countdown of the register delay, once the register reaches 0, the state goes to IDLE.
  • Now it is time to see the Verilog Code, for this logic.
    • Verilog Module pinout:
      module N64_controller(
      		input clk_50MHZ,
      		inout data,
      		input start,
      		output reg [33:0]buttons=34'd0,
      		output reg alive=1'd0
      );

       

    • States and control signals declaration:
      								  //counter_en___finish___oe__get__state
      localparam IDLE_FSM		 =	8'b0___________0________0___0_0000;
      localparam POLL_FSM		 =	8'b0___________0________1___0_0000;
      localparam SEND0_FSM1	 =	8'b0___________0________1___0_0010;
      localparam SEND0_FSM2	 =	8'b0___________0________1___0_0011;
      localparam SEND1_FSM1	 =	8'b0___________0________1___0_0100;
      localparam SEND1_FSM2	 =	8'b0___________0________1___0_0101;
      localparam GET_FSM 		 =	8'b1___________0________0___0_0110;
      localparam FINISH_FSM 	 =	8'b0___________1________0___0_1110;
      
      
      localparam THREEuSECONDS = 32'd150;
      localparam ONEuSECONDS = 32'd50;
      localparam HUNDRED_MS = 32'd400000;
      
      reg [7:0]state=IDLE_FSM;
      reg [31:0]counter_delay =32'd0;
      reg [31:0]counter_delay_pulses =32'd0;
      reg [3:0]counter_polling =4'd0;
      reg [5:0]counting_data =6'd0;
      wire [8:0]polling_data=9'b110000000;
      reg [33:0]buffer_buttons=34'd0;
      reg [7:0]counter=8'd0;
      wire counter_en=state[7];
      wire oe=state[5];
      wire finish=state[6];
      wire counting_data_clk=state[4];
      wire data_out=state[0];
      reg data_in=1'b0;
      reg real_in=1'b0;
      reg start_counter=1'b0;
      assign data = oe ? data_out: 1'bz;

       

    • Main FSM:
      always@(posedge clk_50MHZ)
      begin
      	case(state[7:0])
      	IDLE_FSM	:begin	 	
      					counter_delay[31:0]<=0;
      					state[7:0]<=IDLE_FSM;
      					if(start)
      					begin
      						state[7:0]<=POLL_FSM;
      					end
      				 end
      	POLL_FSM	:begin	 
      					counter_delay[31:0]<=0;// otherwise go to get the data
      					state[7:0]<=GET_FSM;
      					if(counter_polling[3:0]<=4'd8)
      					begin
      						counter_delay[31:0]<=ONEuSECONDS;//send a 1 starting from 1 us
      						state[7:0]<=SEND1_FSM1;
      						if(polling_data[counter_polling[3:0]]==1'b0)
      						begin
      							counter_delay[31:0]<=THREEuSECONDS;
      							state[7:0]<=SEND0_FSM1;//send a 0  starting from 3 us
      						end
      					end
      				 end
      	SEND0_FSM1	:begin// send a 0  
      					state[7:0]<=SEND0_FSM1;
      					counter_delay[31:0]<=counter_delay[31:0]-1'b1;
      					if(counter_delay[31:0]==32'd0)
      					begin
      						state[7:0]<=SEND0_FSM2;
      						counter_delay[31:0]<=ONEuSECONDS;
      					end
      				 end
      	SEND0_FSM2	:begin
      					state[7:0]<=SEND0_FSM2;
      					counter_delay[31:0]<=counter_delay[31:0]-1'b1;
      					if(counter_delay[31:0]==32'd0)
      					begin
      						state[7:0]<=POLL_FSM;
      					end
      				 end
      	SEND1_FSM1	:begin
      					state[7:0]<=SEND1_FSM1;
      					counter_delay[31:0]<=counter_delay[31:0]-1'b1;
      					if(counter_delay[31:0]==32'd0)
      					begin
      						state[7:0]<=SEND1_FSM2;
      						counter_delay[31:0]<=THREEuSECONDS;
      					end
      				 end
      	SEND1_FSM2	:begin
      					state[7:0]<=SEND1_FSM2;
      					counter_delay[31:0]<=counter_delay[31:0]-1'b1;
      					if(counter_delay[31:0]==32'd0)
      					begin
      						state[7:0]<=POLL_FSM;
      					end
      				 end
      	GET_FSM 	:begin	 
      					state[7:0]<=GET_FSM;
      					counter_delay[31:0]<=HUNDRED_MS;// DELAY AFTER POLLING AND GETTING DATA
      				   if(counter[7:0]>=8'd33)// wait untilt there are 33 pulses coming from the N64 controller
      					begin
      						state[7:0]<=FINISH_FSM;
      					end
      				 end
      	FINISH_FSM 	:begin
      					state[7:0]<=FINISH_FSM;
      					counter_delay[31:0]<=counter_delay[31:0]-1'b1;
      					if(counter_delay[31:0]==32'd0)
      					begin
      						state[7:0]<=IDLE_FSM;
      					end
      				 end
      	default		:begin
      					state[7:0]<=IDLE_FSM;
      					counter_delay[31:0]<=32'd0;
      				 end
      	endcase 
      end
      

       

    • Counting pulses GET_FSM state:
      async_trap_and_reset async_trap_and_reset_inst
      (
      	.async_sig(data_in) ,	// input  async_sig_sig
      	.outclk(clk_50MHZ) ,	// input  outclk_sig
      	.out_sync_sig(sync_data) ,	// output  out_sync_sig_sig
      	.auto_reset(1'b1) ,	// input  auto_reset_sig
      	.reset(1'b1) 	// input  reset_sig
      );
      
      
      async_trap_and_reset async_trap_and_reset_inst2
      (
      	.async_sig(~data_in) ,	// input  async_sig_sig
      	.outclk(clk_50MHZ) ,	// input  outclk_sig
      	.out_sync_sig(sync_data_not) ,	// output  out_sync_sig_sig
      	.auto_reset(1'b1) ,	// input  auto_reset_sig
      	.reset(1'b1) 	// input  reset_sig
      );
      
      
      always@(posedge clk_50MHZ)
      begin
      	if(sync_data)
      	begin
      		counter<=counter+1'b1;
      	end
      	else
      	begin
      		counter<=counter;
      		if(!counter_en)
      		begin
      			counter<=0;
      		end
      	end
      end​

       

    • Counter counter_polling:
      always@(posedge data_out, posedge finish)
      begin
      	if(finish)
      	begin
      		counter_polling[3:0]<=4'd0;
      	end
      	else
      	begin
      		counter_polling[3:0]<=counter_polling[3:0]+1'b1;
      	end
      end
      ​


    • Determining the logic level of the incoming signal from the controller:
      always@(posedge clk_50MHZ)
      begin
      	counter_delay_pulses<=counter_delay_pulses;
      	if(sync_data_not)
      	begin
      		buttons[counter]<=(counter_delay_pulses[31:0]>=32'd100);
      	end
      	else if(sync_data)
      	begin
      		counter_delay_pulses<=0;
      	end
      	else
      	begin
      		if(counter_en)
      		begin
      			counter_delay_pulses<=counter_delay_pulses+1'b1;
      		end
      	end
      end
      
      
      ​


  • Once we have taken a look at the FSM diagram and the Verilog description, we can simulate using ModelSim to verify that the designed FSM works properly, and we meet the timing specifications.

    (right click on the image and open into a new window to magnify)


  • Finally, after designing and simulating, we are ready to implement the module using any FPGA board, for this example, the DE0-NANO is used to conduct the experiment.
  • ENJOY!!

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í
 

 

Written by Holguer Andres
 
Materiales:
Parte HW:
  1. Descargue la siguiente plantilla y descomprimala en una ruta sin espacios y corta.
  2. Ahora abra el proyecto Quartus y abra Qsys(Seleccione system.qsys).
  3. 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
  4. Ahora conecte el Frame reader de la siguiente manera: 
  5. Ahora agregue el modulo "Clocked Video Output" y configure de la siguiente forma: 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 datasheet.
  6. Ahora conecte el modulo "Clocked Video Output" de la siguiente forma:
  7. 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
  8. 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.
  9. Ahora guarde los cambios y oprima en "Generate".
  10. 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 datasheet): 
 
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 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.
 

Written by Holguer Andres

 
 
 
 
 

Download Sources for Quartus II: Plantilla para la DE0-NANO
Binary (*.sof): Descargar



Interesting links:
 
If you want to transform your psx controller to uart using your DE0-NANO, download the next sources:
  • Solution(.*sof): Download, GPIO[1] is Tx(UART 9600 bps).
  • Sources for Quartus: Download
    

Python Script for Keyboard/Mouse emulator: 
    


Modify this lines in the python script for emulating any key of your keyboard or mouse.
  • emulate_key(Virtual_Key, Scan_Code,  PSX_BUTTON, Sensitivity)
  • emulate_mouse(Mouse_Button/Move, PSX_BUTTON, Sensitivity)
  • You can changue the communication port in the line 316 "ser = serial.Serial('COM9', 9600)"

 
 
References(PSX Controller Module Decoder):

 

Escrito por Fabio Andres


En este proyecto se utilizan las herramientas la De0-nano (FPGA, Procesador NIOS II, Memoria y pines) en conjunto con una pantalla touch para lograr la visualizacion de un fractal Mandelbrot, y lograr ver las ventajas que tiene poner Hardware en paralelo con Software para realizar procesos matemáticos complejos como los utilizados en la realización de fractales.
El procesador se programa en lenguaje C y la FPGA en el lenguaje de descripción de Hardware Verilog en Quartus II, se utilizan módulos realizados por el docente Holguer Becerra y librerias ya hechas con el fin de apoyar el diseño modular,  y optimizar tiempo y recursos.
 
El touch de la pantalla se utiliza para acercar y alejar la imagen sin necesidad de botones externos, con el fin de ver que mirando de cerca la imagen esta, está compuesta de la misma figura repetidamente, ademas tendra un boton para seleccionar una carga de imagen sin aceleración de hardware y otra implementando aceleracion de hardware para observar las diferencias de estos metodos.
 
Este proyecto esta basado en el capitulo 22  del libro de Pong Chu.
 
Los sources y el Software se puede encontrar en esta página.


5 de mayo de 2014

 
Documentación sobre los fractales de mandelbroot:

                           "Un fractal es un objeto semigeométrico cuya estructura básica, fragmentada o irregular, se repite a diferentes escalas."

Benoit Mandelbrot


-Definición: Los fractales de mandelbroot como todo fractal es un conjunto de figuras conformadas por sucesiones de figuras geométricas, en este caso sucesion por recursion.
                   Estos conjuntos deben su nombre al matemático  Benoit Mandelbrot y se definen así:

                 \left \{ \begin{matrix}   z_0     & = & 0 \qquad \ & \mbox{(término inicial)} \qquad  \\   z_{n+1} & = & z_n^2 + c  & \mbox{(relación de inducción)} \end{matrix} \right.
                  
                  donde C es un numero complejo, con condición de que este numero debe hacer la sucesion convergente para que pertenezca al conjunto del fractal.
                  
                 La conocida representación de este conjunto en el plano complejo es la siguiente:
                
                
 
                  Los fractales tienen actualmente un gran interes en varias ramas de la ciencia ya que estas figuras representan en parte el comportamiento de la naturaleza y es                          aplicable en la optimizacion de muchos procesos actuales.
 
 
- Código en Matlab para obtener un fractal:
 
 
            Código simple:
                
puntos=200;
puntosx=linspace(-2.1,0.9,puntos);
puntosy=linspace(-1.5,1.5,puntos);
[X,Y]=meshgrid(puntosx,puntosy);
C=X+Y*i;
Z=zeros(puntos);
iteraciones=20;
for k=1:iteraciones

Z=Z.^2+C;
W=exp(-abs(Z));
end
pcolor(W);

 

               Resultado:
                 

Código con gráfica mejorada:
 


col=20;
m=400;
cx=-.6;
cy=0;
l=1.5;
x=linspace(cx-l,cx+l,m);
y=linspace(cy-l,cy+l,m);
[X,Y]=meshgrid(x,y);
Z=zeros(m);
C=X+i*Y;
for k=1:col;
Z=Z.^2+C;
W=exp(-abs(Z));
end
colormap copper(256);
pcolor(W);
shading flat;
axis('square','equal','off');​

Resultado:

 
 
Conclusión: Se observó que a mayor cantidad de iteraciones es mejor el resultado pero se tarda mas la GPU en procesar los datos para elaborar la imagen,
cuando se llevo la cantidad de iteraciones a un número muy alto, el programa se bloqueo totalmente lo que demuestra que elaborar estas gráficas requieren 
bastante cantidad de procesamiento.
 
 
_______________________________________________________________________________________________________________________________________________________
 
                     
6 de mayo de 2014


¿ Cómo hacer Zoom en el fractal ?

El algoritmo mas facil de emplear, es hacer que en el display se muestren las coordenadas especificas dentro de un fractal, no expandiendo la imagen, por ejemplo si se tienen las coordenadas de las esquinas de la imagen como 1,1,-1,-1 y la gráfico en cierta resolución, ejemplo 800x600, y quiero hacerle zoom a la esquina superior izquierda, ahora debo visualizar las coordenadas 1,0.5,0.5,0.5 en la misma resolucion lo que dara como resultado hacerle un zoom a la imagen. Lo anterior nos demuestra que entre mas dentro vaya del fractal, las coordenadas deben ser mas exactas y con mas decimales por lo que va a requerir mas procesamiento de datos.


Un código que implementa esto en matlab es el siguiente:
clear all
figure(1); clf;

termination = 1000;
x = linspace(-2,1,640); % si se quiere hacer zoom se debe modificar el -2,1 y -1,1 que son los limites del gráfico.
y = linspace(-1,1,480);
x_index = 1:length(x) ;
y_index = 1:length(y) ;
img = zeros(length(y),length(x));


for k=x_index
    for j=y_index
        z = 0;
        n = 0;
        c = x(k)+ y(j)*i ;%complex number
        while (abs(z)<2 && n<termination)
            z = z^2 + c;
            n = n + 1;
        end
        img(j,k) = n;
    end
end

imagesc(img)
colormap(summer)
 
 

 


8 de mayo de 2014



Resultado zoom in matlab, y generación de fractal en C.


Resultado:

Se ejecuto el código descrito en el dia 6 de mayo y se obtuvieron los siguientes resultados en matlab:
 
 
 
GRÁFICA SIN ZOOM
 
 
 
 
GRÁFICA CON 
x = linspace(-1,1,640); 
y = linspace(-0-5,1,480);
GRÁFICA CON 
x = linspace(-0.2,0.5,640); y = linspace(-0.1,0.5,480);
 
 
 






Código fractal en C

A continuación se tiene un ejemplo de una sub-función que genera el fractal y lo proyecta en un display, este código fue suministrado por el Docente Ing.Holguer Becerra y se tratara de ir explicando que trata cada linea.
 
 
 
 
void generate_fractal(void){             // da nombre y tipo a la sub-función


    int XXX=800; //establece el ancho de la resolución de la pantalla
    int YYY=600; // establece el alto de la resolución de la pantalla
    float Maxx=1;             // Define 1 como el punto más a la derecha de la pantalla.
    float Minx=-1;            //  Define -1 como el punto más a la izquierda de la pantalla
    float Maxy=1;             //  Define 1 como el punto más arriba en la pantalla
    float Miny=-1;            //  Define -1 como el punto más abajo de la pantalla
    float initer=100;          // Establece el número de iteraciones de la funcion(Como en el código Matlab).

    float pixcorx=(Maxx-Minx)/XXX;            //  cada cuanto esta desplazado un pixel verticalmente, la respuesta es 2.5x10^-3 esto quiere decir que despues de -1 el siguiente es -1+2.5+10^-3
    float pixcory=(Maxy-Miny)/YYY;            //igualmente horizontalmente

    image1=create_surface(800,600); // 

    int j=0;

    do                                     //Start vertical loop

    {

        int i=0;

        do

        {

            float x=0;
            float y=0;s
            float xnew=0;
            float ynew=0;
            int k;

            for(k=0;k<=initer;k++)  // Se repite la función tanto, como el número de iteraciones
            {
             //The Mandelbrot Function Z=Z*Z+c into x and y parts   

             xnew=x*x-y*y + i*pixcorx+Minx;  // estableciendo direccion del punto vertical segun la funcion de mandelbroot vista anteriormente
             ynew=2*x*y   + Maxy-j*pixcory;  // estableciondo direccion del punto horizontal 
             x=xnew;
             y=ynew;
             if ( (x*x+y*y)>4 ){break; } // Criterio de permanencia en la función
            }

               int color = k;            // estableciendo color
               if (color>color/2){
                   color=color%0xffffff;
               }
               else{

               }
               if (k>=initer){

               }
               else{
                   set_pixel(i,j,colors[color%10],image1);  // envia las direcciones y el porcentaje de brillo del punto a dibujar.
               }

             i++;

        }while ( (i<XXX));  //Finaliza ciclo horizontal

        j++;

    }while ( (j<YYY));        //Finaliza ciclo vertical

}​
 

 

 
Nota: Esta sub-función en conjunto con otro código, generará el fractal mediante software (sin aceleración hardware) en el display cuando se seleccione el boton de mostrar sin aceleración hardware.
 
 
Conclusión gráfico Matlab: Se comprobó que el codigo funciona, ademas se observó que entre mas se hace zoom, mas se demora el computador en arrojar la gráfica, y que si se quiere mas detalle en el zoom es necesario hacer mas iteraciones por lo que esta acción (hacer zoom) requiere aun mas procesamiento que obtener la gráfica del fractal normalmente.
 
Conclusión código: Se afianza el concepto de que el número de iteraciones juega un papel muy importante en el código ya que de estas dependen la calidad y precisión del gráfico, pero esto tiene un costo en el consumo de recursos, que se va a poder mitigar en un futuro con ayuda de hardware.
 
 
 
______________________________________________________________________________________________________________________________________________________________________
 
 
10 de Mayo de 2014

Empezando con el capitulo 22 del libro EMBEDDED SoPC DESIGN WITH NIOS II PROCESSOR  AND VERILOG EXAMPLES de PONG CHU


En este capitulo CHU implementa el mismo algoritmo usando una rutina software y un acelerador de Hardware para generar un fractal, hacer zoom y visualizarlo en una pantalla con VGA.


Explicación del algoritmo:

 en algoritmo de CHU no se usa la ecuación matemática con números complejos:
 
Si no que hace una conversión de esta ecuación en coordenadas cartesianas de la siguiente manera:
 
 
Para determinar el valor de las constantes Cx y Cy no existe una fórmula para saberlo, y se necesitaría realizar un número infinito de iteraciones. Por ello en el algoritmo se usa una restricción, cuando alguno de los dos Xn y Yn sea mayor a cuatro se dirá que el punto no esta en el conjunto, y ello depende del número de iteraciones a realizar, ya que si por ejemplo se realizan 100 iteraciones y el numero es superior en la iteracion número 98, se dirá que el punto no esta en el conjunto, pero si se tiene con esos mismos valores 50 iteraciones se dirá que si esta en el conjunto ya que no alcanza a la iteracion número 98.
 
Sub-función Calc_frac_point:
 
 
 
    
calc_frac_point(cx, cy, max_itr){
    x = cx;
    y = cy;
    itr=0;
    do {
            xx = x * x;
            yy = y * y;
            xy = x * y;
            y = x2 - y2 + cx;
            x = xy*2 + cy;
            itr + + ;
          } while ((xx+yy)<4.0 && i t r < m a x _ i t r ) ;
    r e t u m (itr ) ;
    }​
 

 
Esquema de color:

Para hacer mas interesante la gráfica, se realizan escalas de color de acuerdo al resultado de la ecuación, si se tiene:
 
 Con M=max iteraciónes y n= al numero de return(itr)
 
El gráfico obtenido seria el siguiente:
 
 
Se pueden añadir mas colores para un mejor efecto del gráfico del fractal, por ejemplo:
 
 Donde K=número de colores soportados por la pantalla.
 
Y se obtendría un gráfico como el siguiente:
 
 
 
Generación de una imagen fractal


Para obtener la imagen en el display, es necesario, ademas de obtener los valores Cx y Cy ubicarlos en un plano y poner un color de acuerdo al numero de la iteración en el pixel indicado, la distancia entre cada pixel esta dado por:
 
 
Un código que genera esto puede ser el siguiente:
 
 
Cy = Cy0;
for(j=0; j<HPIX; j++){
    Cx = cxO;
    for(i=0; i<VPIX; i++){
        itr = calc_f rac_point (ex , cy, max_i.tr);
        color = assign.color(itr);
        display.pix (i, j, color);
       Cx = Cx + delta;
        }
cy = cy + delta;
}​
 
 

 
 
 
______________________________________________________________________________________________________________________________________________________________________
 

12 de mayo de 2014(Ya le envié un correo, corregir..)
 
implantación del código en NIOS II
 
Se harán uso de los drivers de VGA usados en el laboratorio cuatro de la materia para visualizar el fractal en el display, el main principal de todo el proyecto queda algo como lo siguiente:
 
 
sub-funcion para generar el color del pixel:
 
unsigned int colors[10]={GREEN_24,AQUAMARINE_16,BROWN_16,BLUEVIOLET_16,INDIGO_16, LEMONCHIFFON_16,OLIVE_16,SILVER_16, DIMGRAY_24,GOLD_24};
 
 
 
int color(iter,max_iter )
{
int p;
int color;

if(iter==max_iter)
{
color=0x0000;
}
else
{
p=iter%10;
color=p;

}


return(color);
}
 ​
 
 
 
 
sub-funcion para generar el fractal
 
 
 
 
int calc_frac_point(cx, cy, max_itr){
int xx;
int x;
int y;
int yy;
int xy;
int x2;
int y2;
int itr;

x = cx;
    y = cy;
    itr=0;
    do {
            xx = x * x;
            yy = y * y;
            xy = x * y;
            y = x2 - y2 + cx;
            x = xy*2 + cy;
            itr ++ ;
          } while ((xx +yy)< 4 && (itr<max _itr));
    return (itr) ;
    }​
 
 

 

programa principal:
 
 
 
int cy;
  int cy0;
  int cx0;
  int cx;
  int j;
  int i;
  int HPIX;
  int VPIX;
  int delta;
  int itr;
  int max_itr;

  int xn;
  int yn;
  // resolución de la pantalla
  HPIX=480;
  VPIX=272;
  delta=99;
  // Area de dibujo del fractal
  cx0=0;
  cy0=0;
  xn=480;
  yn=272;
  // cálculo de delta

  delta= xn-cx0/HPIX; // delta= 1




   while(1){

   cy = cy0;
   for(j=0; j<HPIX; j++){
   cx = cx0;
   for(i=0; i<VPIX; i++){
   itr = calc_frac_point (cx , cy, max_itr);
   color = color(itr,max_itr);
    vid_set_pixel(j,i,color,pReader);
   cx = cx + delta;
   }
   cy = cy + delta;
   }

   }
   return 0;
   }​
 
______________________________________________________________________________________________________________________________________________________________________
 
 
 
13 de mayo de 2014


Corrección del código del día de ayer y resultados.

El código mostrado en la fecha del 12 de mayo posee ciertos errores, como este código es sacado directamente del libro de PONG CHU, significa que en el libro se presentan estos mismos errores, por lo que se mandó un correo para que corrigieran dicho error.
 
El código corregido es el siguiente:
 
 
 
- Sub-función que cálcula el fractal:

 

int calc_frac_point(float cx, float cy, float max_itr){
float xx;
float x;
float y;
float yy;
float xy;
float x2;
float y2;
float itr;

x = cx;
    y = cy;
    itr=0;
    do {
            xx = x * x;
            yy = y * y;
            xy = x * y;
            x = xx - yy + cx;
            y = xy*2.0 + cy;
            itr ++ ;
          } while (xx+yy<4.0 && (itr<max_itr));
    return (itr) ;
    }
 


- Sub-función para obtener colores:


 
 
int assign_color(int iter,int max_iter )
{
int p;
int color;

if(iter==max_iter)
{
color=0x0000;
}
else
{
p=iter%10;
color=colors[p];

}


return(color);

}​
 
 
 
 
- Programa principal:
 

 
 
int main(){


//***** INICIALIZANDO DRIVERS ****//


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


result=alt_touchscreen_init(
   &touchscreen_global,
   TOUCH_PANEL_SPI_BASE,
   TOUCH_PANEL_SPI_IRQ,
   TOUCH_PANEL_PENIRQ_N_BASE,
   60,
   ALT_TOUCHSCREEN_SWAP_XY);

if(result==0){
printf("Touch Inicializado\n");

alt_touchscreen_calibrate_upper_right (&touchscreen_global,
3975,   4032,    // ADC readings
 479,      0  ); // pixel coords
alt_touchscreen_calibrate_lower_left  (&touchscreen_global,
112,    110,     // ADC readings
  0,    271  );  // pixel coords
}
else{

printf("Touch Fallo\n");
return 0;
}

// init video

 VIP_FRAME_READER *pReader;

   ////////Se inicializa el HW del sistema//////////////
   // frame reader

   pReader =  VIPFR_Init(ALT_VIP_VFR_0_BASE, (void *)FR_FRAME_0, (void *)FR_FRAME_0, FRAME_WIDTH, FRAME_HEIGHT);

  // se activa el frame de video
   VIPFR_ActiveDrawFrame(pReader);



   // clean screen
   vid_clean_screen(pReader, BLACK_24);



   printf("Video Inicializado\n");


   //***** PROGRAMA PRINCIPAL ****//
  float cy;
  float cy0;
  float cx0;
  float cx;
  int j;
  int i;
  int HPIX;
  int VPIX;
  float deltax;
  float deltay;
  int itr;
  int max_itr;
  int color;
  float xn;
  float yn;
  // resolución de la pantalla
  HPIX=480;
  VPIX=272;
  // Area de dibujo del fractal
  cx0=-2;
  cy0=-1;
  xn=1;
  yn=1;
  // cálculo de delta

  deltax=(float)(xn-cx0)/(float)HPIX;
  deltay=(float)(yn-cy0)/(float)VPIX;
  max_itr=200;



    while(1){

cy = cy0;
for(j=0; j<VPIX; j++){
cx = cx0;
for(i=0; i<HPIX; i++){
itr = calc_frac_point (cx , cy, max_itr);
color = assign_color(itr,max_itr);
vid_set_pixel(i,j,color,pReader);
cx = cx + deltax;
}
cy = cy + deltay;
}
}


return 0;
}
​
 
 
 
 
RESULTADOS:


10 iteraciones:

 
100 iteraciones 
 
 
 
 
 
1000 iteraciones
 
 
 
 
 
vídeo que muestra los resultados finales:
 
 
 
 
______________________________________________________________________________________________________________________________________________________________________
 
15 de mayo de 2014

PASANDO DE FORMATO IEEE FLOTANTE A FORMATO q4.28.


El código mostrado anteriormente utiliza el formato estándar IEEE para manejar flotantes, se pasará ahora a utilizar a un nuevo format con el fin de optimizar recursos y hacer la implementacion de un acelerador de hardware mas fácil y una alternativa son los formatos de punto fijo.

Estos formatos constan de un entero y factor de escala que no varia, por ejemplo si se tiene cinco decimales y un factor de escala de 10^-3 el valor 12.345 puede ser representado como 12345*10^-3
el 10^-3 a diferencia del punto flotante no varia.

Estos tipos de notaciones se representan como de tipo Qm.f donde m es el número de dígitos enteros y f el factor de escala, el ejemplo anterior es de tipo Q2.3.

Para sumar o restar dos números de estos formatos solo hay que sumar o restar los números enteros y dejar el factor de escala intacto, produciendo el resultado en el mismo formato excepto cuando hay desbordamiento.
 
Para multiplicar números se multiplican los enteros y el factor de escala es el doble de los factores de escala, es decir un producto de dos Qm,f da como resultado en número en formato Q2m,2f si se quiere obtener el mismo formato, se debe hacer un recorte de los digitos mas o menos significativos aunque esto nos hace perder precisión que es la principal desventaja de este tipo de formatos.
 
Es importante escoger un rango de operaciones para que las operaciones no den desbordamiento.
 
Se observa que la principal ventaja de este formato es que se pueden usar las mismas operaciones de los números enteros con desplazamiento de números.
 
 
______________________________________________________________________________________________________________________________________________________________________
 
19 de mayo de 2014


Código implementando el sistema decimal  y resultados


Debido a que el lenguaje C no tiene soporte para tipo de datos de punto fijo, estos se deben manipular manualmente para su buen funcionamiento, como el NIOS II es de 32 bits, escojeremos este tamaño para el número de punto fijo, luego mirando el rango de datos en los ejes del fractal de mandelbrot que van de (-2,2) se selecciona el formato de punto fijo Q4.28  (cuatro bits enteros y 28 bits como fracción).
 
 
Explicación del formato Q 4.28:
 
En este formato los primeros 4 bits osea el primer nibble esta dedicado a representar el entero en complemento a dos, y los siguientes 28 bits o 7 nibbles a representar la fracción del número.
 
 
ejemplos:
 
1)
 por ejemplo si se quiere representar el número 2,5:
 
 
 
 
Se debe poner en el primer nibble el número dos que es 0010 y en la parte decimal el número 0,5, sabiendo que el peso de los números van a ser 2^-1-->2^-2-->2^-3, se debe poner el número ocho en binario 1000 ya que 1*2^-1=0,5. Reuniendo ambos componentes el número 2,5 en formado Q.4.28 es
 
                                                                                                                                                                        0010-1000-0000-0000-0000-0000-0000-0000
                                                                                                                                                                                                       0x280000000 (en hexadecimal cada nibble binario representa un número que va de 0 a F)
2)
El número 1,7 tendria:
 
parte entera--> 0001
 
parte decimal ---> una aproximación cercana puede ser 1011001 que representa 0,6953125 si se múltiplica por su respectivo peso como se explico anteriormente.
 
Reuniendo 1,7 en fomato Q 4.28 es
 
                                                                                                                                                                      0001-1011-0010-0000-0000-0000-0000
                                                                                                                                                                                                0x1B200000
 
3)
El número -7.5
 
Parte entera debe usarse con complemento a dos es decir se niega el número 7 y luego se suma uno:
 
  7--> 0111--> 1000+1---> 1001
 
La parte decimal es la mima que la del primer ejemplo, por lo que se tiene que -7,5 en Q 4.28 es:
 
                                                                                                                                                                          1001-1000-0000-0000-0000-0000-0000-0000
                                                                                                                                                                                                    0x98000000

4) 
El número 5.025

Parte entera--> 0101
 
Parte decimal --> sabiendo que 2^-2=0.25 se tiene el número 0100
 
en formato Q 4.28
                                                                                                                                                                            0101-0100-0000-0000-0000-0000-0000-0000
                                                                                                                                                                                                    0x54000000
                                                                                                                                                                                         

 
 
 
La implementación de este formato en el código anteriormente descrito se muestra a continuación (sacado del libro de PONG CHU):
 
 
 
 
int calc_frac_point_soft( fixed428 cx, fixed428 cy, alt_ul6 max_i.tr)
{
    fixed428 x, y, xx, yy, xy2;
    fixed856 xx_raw, yy.raw, xy.raw;
    int itr;
    x = cx;
    y = cy;
    itr=0;
    do {
            /* Q4.Z8 multiplications */

                xx_raw= (fixed856)(x) * (fixed856)(x);

                xx = (fixed428)(xx_raw » 28);

                yy_raw = (fixed856)(y) * (fixed856)(y);

                yy = (fixed428)(yy_raw >> 28);

                xy_raw=. (fixed856)(x) * (fixed856)(y);

                xy2 = (fixed428)(xy_raw » 27); // 2* is same as «1

                /* iteration equation */

                x = xx - yy + cx;

                y =  xy2 + cy;
        
                itr++;
        
                } while (((xx+yy)<0x40000000) && ( itr < max_itr ) ) ;

       return(itr);
    
       }​

 

 
los codigos .c los encuentran aca:
 
 
 
 
 
Resultados de mejoramiento de tiempo:


tiempo de NIOS IIf con punto flotante: 2 minutos 30 segundos es decir 150 segundos
 
tiempo de NIOS IIf con fixed point: 30 segundos
 
lo que quiere decir que el tiempo se optimizó cinco veces.
 
además de eso el dibujo se muestra mas detallado como se ve en las siguientes figuras:
 
 
punto flotante:
 
 
punto fijo:
 
 
 
 
_________________________________________________________________________________________________________________________________________________________________________
 
23 de mayo de 214

Implementación formato q8.56, en este tipo de formato la parte entera consta de 8 bits y la parte decimal de 56 bits
 
 
 
Conclusión: El sistema Nios II no posee la arquitectura suficiente para hacer este tipo de formato ya que la parte del código en el cual se usa el doble formato para guardar el cuadrado de la variable x no se puede obtener, se necesitaría declarar una variable de 128 bits y esto no es posible tocaria dividirla en dos variables.
 
Se trato de realizar usando el tipo long long pero al ir a la página de altera (ver tabla 1)  se observa que es de 8 bytes por lo tanto es insuficiente para las necesidades que se requiere.
 
Como conclusión se tiene que no se va a implementar este sistema debido a que la única manera de hacerlo es dividiendo los datos y hacer operaciones por partes, por lo que las operaciones en el código aumentarían y consigo el tiempo en que se demoraría en dibujar el fractal entonces este método no estaría optimizando el sistema, que es el objetivo del proyecto. 

 
 
Tabla 1 (fuente: http://www.altera.com/literature/hb/nios2/n2cpu_nii51016.pdf)
 
 
 
 EMPEZANDO IMPLEMENTACIÓN HW:

Despues de realizar el algoritmo para calcular el fractal en lenguaje C, implementarlo en HDL resulta fácil   mediante una maquina de estados finitos, el código HDL se muestra a continuación:
 
 
module Mandelbrot
    #(
        parameter W= 32, // width (# bits) of Qm. 
        parameter M= 4 // # of bits in m
    )
    (
        input wire clk, reset ,
        input wire start,
        input wire [W-1:0] cx, cy,
        input wire [15:0] max_it,
        output reg [15:0] iter,
        output reg idler
		  
    );

    // constant declaration
     localparam F = W - M; // # of bits in fraction

    // symbolic state declaration

    localparam [3:0] idle=4'b0001;
      localparam [3:0] load_data=4'b0010;
		localparam [3:0]  operation1= 4'b0011;
		localparam [3:0]  finish= 4'b0100;
		 localparam [3:0] resetea=   4'b0101;
		 localparam [3:0] finaliza=   4'b0110;
		 
		 localparam [3:0]  operation2= 4'b0111;
		 localparam [3:0]  operation3= 4'b1000;
		 localparam [3:0]  operation4= 4'b1001;
		 localparam [3:0]  operation5= 4'b1010;

		 
		  
		  
		  

    // signal declaration
    reg [3:0] state_reg, state_next;
    reg [15:0] it_reg , it_next;
    reg signed [2*W-1:0] xx_raw, yy_raw, xy_raw;
    reg signed [W-1:0] xx, yy, xy2;
    reg signed [W-1:0] x_reg, x_next, y_reg, y_next;
    reg signed [W-1:0] cx_reg, cx_next, cy_reg, cy_next;
	 wire	reset1;
    wire escape;
    reg frac_ready_i, frac_done;
	 reg reset_reg;
	 reg [31:0] suma;

     // body
    // FSMD state-data registers
    always@(posedge clk)
    begin
        if (reset)
            begin
                    state_reg <= idle;
                    it_reg <= 0;
                    x_reg <= 0;
                    y_reg <= 0;
                    cx_reg <= 0;
                    cy_reg <=0;
              end
        else
				begin
					case (state_reg[3:0])
					
					idle:											
							begin
							
							idler<=1'b1;
							
							if(start==1'b0)
								begin
									state_reg<=idle;
								end
							else
								begin								
									state_reg<=load_data;
								end
								
							end
							
					load_data:
							begin
							
							idler<=1'b0;
							
							x_reg<=cx; //x = cx;
							y_reg<=cy; //y = cy;				
							
							cx_reg<=cx; // nunca se modifican
							cy_reg<=cy; // nunca se modifican
							
							state_reg<=operation1; 
													
							end
					operation1: 
							begin
								state_reg<=operation2;  //while
								idler<=1'b0;
								xx_raw <= x_reg * x_reg; //   xx_raw= (fixed856)(x) * (fixed856)(x);	
							end
						
					operation2:
							begin
								state_reg<=operation3;  //while
								idler<=1'b0;
								xx<= xx_raw[2*W-1:28] ; //  xx = (fixed428)(xx_raw >> 28);
								yy_raw <= y_reg * y_reg; //   yy_raw = (fixed856)(y) * (fixed856)(y);
							end
					operation3:
							begin
								state_reg<=operation4;  //while
								idler<=1'b0;
								yy <=  yy_raw >> 28; //    yy = (fixed428)(yy_raw >> 28);
								xy_raw <= x_reg * y_reg; //  xy_raw=(fixed856)(x) * (fixed856)(y);
							end
					operation4:
							begin
							
								state_reg<=operation5;  //while
								idler<=1'b0;
								
								xy2 <= xy_raw >> 27 ; // xy2 = (fixed428)(xy_raw>>27); // 2* is same as «1															
							  x_reg<= xx-yy+ cx_reg;    //   x = xx - yy + cx; 
							  
							  suma<= xx+yy;
							  
							  end
		
					operation5:
							begin
							  y_next<=  xy2+cy_reg;  //     y =  xy2 + cy;
							  it_reg<=  it_reg +1;  //     itr++;
							  
							  if((suma<32'h40000000) && ( it_reg <  max_it )) //while (((xx+yy)<0x40000000) && ( itr < max_itr ) ) ;
								begin
								state_reg<=operation1;  //while
																		
								end
								else
								state_reg<=finish;
							
								
							end
			
					finish:
						 begin
						  idler<=0;
						  it_reg <= 0;
                    x_reg <= 0;
                    y_reg <= 0;
                    cx_reg <= 0;
                    cy_reg <=0;
						  iter<=it_reg; //return(itr);
						  state_reg<=idle;
						  end
						  
					default:
						begin
							state_reg<=idle;
						end
			endcase
			
			end
		end
		
		

			
endmodule
______________________________________________________________________________________________________________________________________________________________________
 
Explicación de la implementación del psx para mover el fractal:


Para mover el fractal de  derecha a izquierda y de arriba a abajo, el zoom in y el zoom out se hizo uso de un control de play station 2, los sources de la decidificacion y la explicación de como se hace se encuentra en el link: DE0 NANO PlayStation Controller Interface
 
 
En este proyecto se usaron los análogos del control, con el fin de tener algún control sobre la intensidad o velocidad de los movimientos; los controles analogos tienen como resultado en su parte digital dos vectores, uno para el movimiento arriba-abajo y el otro izquierda-derecha,  cada movimiento se representa mediante vectores de _____ bits, donde el cero es el número 124 y varia de acuerdo al movimiento, se usó este numero para multiplicarlo con los margenes del código del fractal en el NIOS II, ademas se utilizaron los botones up-down-left-right digitales para tener mas control de los movimineots y de esta manera tener movimientos bruscos o suaves como se explica a continuación en el siguiente código comentado:
 
 
 
 
 
 
 
while(1){

    analog1x=IORD( ANALOG1_X_BASE,0); // lee el vector de derecha-izquierda del análogo uno del control psx


    analog1y=IORD( ANALOG1_Y_BASE,0); // lee el vector de arriba a abajo del análogo uno del control psx

    analog2x=IORD( ANALOG2_X_BASE,0); // lee el vector de derecha-izquierda del análogo dos del control psx

    analog2y=IORD( ANALOG2_Y_BASE,0); // lee el vector de arriba a abajo del análogo dos del control psx

    if(IORD(BOTON_UP_BASE,0)==1){   // Si en el control se presiona el boton arriba, el número incd incrementa
    incd++;
    }
    else if(IORD(BOTON_DOWN_BASE,0)==1){  // Si en el control se presiona el boton abajo, el número incd decrementa
    incd--;
    }


  
    if(analog1y>128){  //  si se mueve el analogo1 hacia arriba los margenes del fractal aumentan en y  es decir la                                                      //   imagen se mueve hacia arriba con la sensibilidad dada por (analog1y/incd)
    cy0=cy0+(0x1<<(analog1y/incd));
    yn=yn+(0x1<<(analog1y/incd));

    draw++;

    }
    else if(analog1y<128){//  si se mueve el analogo1 hacia abajo los margenes del fractal disminuyen en y es decir                                                     //la    imagen se mueve hacia abajo con la sensibilidad dada por (analog1y/incd)
    cy0=cy0-(0x1<<((255-analog1y)/incd));
yn=yn-(0x1<<((255-analog1y)/incd));
draw++;
    }

    if(analog1x>128){//  si se mueve el analogo1 hacia la derecha los margenes del fractal aumentan en x es decir                                                     //la    imagen se mueve hacia la derecha con la sensibilidad dada por (analog1y/incd)
    cx0=cx0+(0x1<<(analog1x/incd));
    xn=xn+(0x1<<(analog1x/incd));
    draw++;

    }
    else if(analog1x<128){//  si se mueve el analogo1 hacia la izquierda los margenes del fractal disminuyen en x es decir                                                     //la    imagen se mueve hacia la izquierda con la sensibilidad dada por (analog1y/incd)
    cx0=cx0-(0x1<<((255-analog1x)/incd));
xn=xn-(0x1<<((255-analog1x)/incd));
draw++;
    }


    if(analog2y<128){ //  si se mueve el analogo2 hacia la arriba los margenes del fractal iniciales Cx0 y Cy0 aumentan y 
                                        // los finales disminuyen  esto tiene el efecto de alejar la imagen.

    cx0=cx0+((255-analog2y)<<2);
xn=xn-((255-analog2y)<<2);
cy0=cy0+((255-analog2y)<<2);
yn=yn-((255-analog2y)<<2);
draw++;
    }
    else if(analog2y>128){//  si se mueve el analogo2 hacia la abajo los margenes del fractal iniciales Cx0 y Cy0 disminuyen y 
                                        // los finales aumentan  esto tiene el efecto de acercar la imagen.
    cx0=cx0-(0x1<<((analog2y)/incd));
xn=xn+(0x1<<((analog2y)/incd));
cy0=cy0-(0x1<<((analog2y)/incd));
yn=yn+(0x1<<((analog2y)/incd));
draw++;
    }​
 
 
 
 
 
 
______________________________________________________________________________________________________________________________________________________________________
 
Gracias por su visita :)


Vídeo del resultado final:
 
 
 
 
 
 
Written by Holguer Andres
 
 
Welcome to FPGA lover!!!
 
Currently, I am moving all my web courses to a single one(www.fpgalover.com) using solely Terasic/Altera Boards. This Web page will have soon all my tutorials including the content of all my courses among I have:
 
 
While this is done, please I invite you to take a look at the new manuals on the web page, and have a tour, Enjoy, and Love FPGAs!
 
PS: Register to get access to exclusive tutorials and manuals.
 
Best Regards.
 
 

Monday, 20 November 2017

Written by Fabio Andres     In this manual you are going to understand how the SNES Controller Works, and how we can acquire through a simple Finite State Machine (FSM), all the buttons states from the SNES controller using the de0-nano SOC (you can use any FPGA borad, and implement this manual). It is important to make clear that this manual is based on "SNES timing diagram"(Design Methodology) by Thomas D.   Required Materials: Any FPGA board (Though for this manual we...

Explore

Monday, 20 November 2017

Written by Ernesto Andrés Rincón Cruz Nios® II is an softcore 32-bit processor developed by Altera to be implemented over all Altera (INTEL) FPGA and SoC families.  Some NIOS-II features: No license required. Use fewer than 700 logic elements. 6-stage pipeline runnning up to 30 DMIPS at 175 MHz in Nios II /e "economy" processor (Dhrystones 2.1 benchmark). Deterministic and jitter free real-time performance. Vector Interrupt Controller. Custom instructions (ability...

Explore

Monday, 20 November 2017

Written by Holguer Andres   Introduction to HLS (High Level Synthesis) Using Verilog, or VHDL as a hardware description language might be difficult for software centric people who have to break the mental paradigm between concurrent software, and concurrent hardware, which sometimes can be confusing, and could be a pain in the ass for many. In addition, while designing a product, or developing a new prototype, using Verilog, or VHDL can be rigorous and tedious, due to the required time...

Explore

Monday, 20 November 2017

Written by Holguer Andres   W5100 Qsys Component.   This Qsys component has been designed to be used with the chip Wiznet W5100 alongside the soft-core Nios II. This manual will tell you how to implement it using the DE0-NANO, and C5GX, and is divided into two parts: Hardware Part. Quartus Project. Qsys. PINOUT Connections. Software Implementation. WebServer Example. Requirements W5100 module. Option 1(Tested). Option 2(Tested). DE0-NANO (Not to be...

Explore

Monday, 20 November 2017

  Written by Holguer Andres Requirements: DE0-NANO-SOC with and SD-CARD preloaded with the following Linux Image (compiled and customized by Holguer Andres). Putty.  Procedure: Using putty open the Linux Terminal through the UART port at 115200 bps. On the Console type: nano /etc/inittab​ As you can observe in the next image, and highlighted in red, all the initial system processes init with ":sysinit:" and next to this a command or a script that is going to...

Explore

Monday, 20 November 2017

  Written by Holguer Andres   In this manual you are going to understand how the N64 Controller works, and how we can acquire through a simple Finite State Machine (FSM), all the buttons states from the N64 controller using the DE0-NANO (you can use any FPGA board, and implement this manual). it is important to make clear that this manual is based on http://larsivar.com/wp/?p=86 manual in which it is explained the N64 controller protocol, there is a software example for acquiring the...

Explore

Monday, 20 November 2017

How you can turn on debug messages on Qsys If you have already created a qsys file, just follow the next steps Close the <>.qsys file you are working with. Open the file called <preferences.xml>, which is in the folder where your <>.qsys file is. Look for a line with  Replace the line with  Reopen the <>.qsys file you are working with, and you must see on the loading console some new messages which look like these (green bugs):

Explore

Monday, 20 November 2017

  Setting the D5M Terasic Camera using Nios II at 1920x1080 Written by Holguer Andres Requirements: Quartus Version Above or equal to 14.1 D5M Camera. RAM (Where we can store the video acquisition). HDMI/VGA/SDI, or others video outputs (to stream out the video in order to see the results). This manual is composed by two sections: Hardware description part.In this part you can learn how to create a video acquisition system using Qsys. Software part.In this part you will learn...

Explore

Monday, 20 November 2017

Written by Juan David   Introducción  El proyecto FPGArduino consiste en transformar el uso que normalmente se le da a la FPGA y usarlo como un sistema de micro controladores programables usando Arduino. El sistema consiste en construir una “CPU CORE” que ejecuta subgrupos de cualquier RISC-V o MIPS grupo de instrucciones.   ¿Qué es softcore? Es un microprocesador de núcleo que puede ser implementado en su totalidad mediante la síntesis de la lógica. Se puede...

Explore

Monday, 20 November 2017

Written by Fabio Andres   NIOS II PROCESSOR - Hardware Nios II is an embed processor of structure of 32 bits specifically designed for FPGAs of the brand Altera (Intel).  Nios II has many improvements with the original architecture niosll/e, therefore is more suitable for a huge kinds of informatics applications such as DSP and control systems, moreover, Nios II processor is the world's most versatile processor, according to Gartner Research, and is the most widely used soft processor...

Explore

Monday, 20 November 2017

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...

Explore

Monday, 20 November 2017

Written by Holguer Andres             Download Sources for Quartus II: Plantilla para la DE0-NANO Binary (*.sof): Descargar Interesting links: https://sites.google.com/site/tecnicasdigitales22012/proyecto-final http://www.gamesx.com/controldata/psxcont/psxcont.htm http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/   If you want to transform your psx controller to uart using your DE0-NANO, download the next...

Explore

Monday, 20 November 2017

  Written by Holguer Andres   Materiales: DE0-NANO. 4.3inch-480x272-Touch-LCD.   Parte HW: Descargue la siguiente plantilla y descomprimala en una ruta sin espacios y corta. Ahora abra el proyecto Quartus y abra Qsys(Seleccione system.qsys). Una vez en Qsys, agregue el modulo llamado "Frame Reader" y configure de la siguiente manera:  El Frame Reader, leerá directamente de la RAM una sección de memoria con las características que están en el...

Explore

Monday, 20 November 2017

Escrito por Fabio Andres En este proyecto se utilizan las herramientas la De0-nano (FPGA, Procesador NIOS II, Memoria y pines) en conjunto con una pantalla touch para lograr la visualizacion de un fractal Mandelbrot, y lograr ver las ventajas que tiene poner Hardware en paralelo con Software para realizar procesos matemáticos complejos como los utilizados en la realización de fractales. El procesador se programa en lenguaje C y la FPGA en el lenguaje de descripción de Hardware...

Explore

Monday, 20 November 2017

Written by Jesus Basado en la practica de PicoCtrl del Prof. Yair Linn. OBJETIVOS  Aprender como funciona y como programar el microcontrolador PicoCtrl, adquiriendo conocimiento de como funciona un microcontrolador. INTRODUCCIONUn microcontrolador es un circuito integrado de alta escala de integración que incorpora la mayor parte de los elementos que configuran un controlador. Un microcontrolador dispone normalmente de los siguientes componentes: Procesador o UCP (Unidad...

Explore

You can contribute and make this a better place by supporting it.
if you like this webpage, or if the resources of this webpage are useful for you, please donate.

Paypal(Own Amount)


Donate Rapidly 5 USD:

Donate Rapidly 10 USD: