Welcome to IDI Electronica!!!



Welcome!!! IDI Electronica is a blog for my personal projects and articles to help electronics enthusiasts like me.

Bienvenidos!!! IDI Electronica es un blog con mis proyectos personales y artículos con el fin de ayudar a entusiastas de la electrónica como yo.

Wednesday, June 25, 2014

Mojo v2 Placa de Desarrollo de FPGA

Hace un par de años, ayudé a financiar un proyecto de Embedded Micro para crear Mojo (se pronuncia mou-llo), una placa de desarrollo de FPGA. La placa contiene:

- FPGA Spartan-6 XC6SLX9
- 84 pines de entrada/salida (I/O)
- 8 pines de entrada análoga
- 8 LEDs de uso genérico
- 1 botón de reinicio (reset)
- 1 LED para el estado de configuración del FPGA
- Regulador de voltaje entrante para 4.8V - 12V (5V recomendado)
- Microcontrolador ATmega32U4 para configurar FPGA, interfaz de USB y leer pines análogos
- Memoria flash integrada a la tarjeta para el archivo de configuración del FPGA

El microcontrolador usa una secuencia de arranque compatible con Arduino, para permitir cargar código usando simplemente USB. Embedded Micro también provee un cargador basado en java para cargar el codigo .bin para el Spartan-6 usando simplemente USB.

Esta placa de desarrollo me pareció muy conveniente gracias al potente FPGA Spartan-6. Además, en comparación a la mayoría de placas de desarrollo ofrecidas por Xilinx o Altera, el precio de ~$80 es de fácil acceso para los entusiastas.

Si deseas comprar la placa, o buscar instrucciones para descargar e instalar los programas requeridos por el Mojo, vista la página web de Embedded Micro.

Para la mayoría de mis proyectos de FPGA en este blog, estaré usando el Mojo v2.





Máquina de Estado Finita en Verilog - Usando botón para transiciones

Este código es un ejemplo de una máquina de estado en Verilog y puede ser usado en la placa de FPGA  Mojo.

El código enciende uno de los 8 LEDs a la vez en el Mojo. El LED encendido cambia cada vez que el botón de reinicio (Reset) en el Mojo es presionado.


module LED_state_machine1(

    input   clk,          
// reloj de 50MHz   
    input   nRst,
          // entrada de botón reset   
    input   cclk,         
// reloj del microcontrolador AVR
    output  reg[7:0]led,   // salida a 8 LEDs en tarjeta  
    


  // las siguientes conexiones son para el microcontrolador en el Mojo
    output  spi_miso,          // conexiones SPI para AVR
    input   spi_ss,
    input   spi_mosi,
    input   spi_sck,

    output  [3:0] spi_channel, // AVR selección de canal
    input   avr_tx,            // AVR Tx => FPGA Rx
    output  avr_rx,            // AVR Rx => FPGA Tx
    input   avr_rx_busy        // AVR Rx buffer lleno
    );

// sólo para Mojo. asignar alta impedancia si pines no son usados.
assign  spi_miso = 1'bz;
assign  avr_rx = 1'bz;
assign  spi_channel = 4'bzzzz;


reg       rst;     // crea registro para botón

reg  [3:0]state=0; // crea registros para estados

always@(posedge clk)
 rst <= ~nRst;     // connects reset button to rst register


//beginning of state-machine
// inicio de máquina de estado
always@(posedge rst)  // máquina transiciona si rst es presionado
   begin              // comenzar secuencia de máquina de estado
    case(state)
     3'd0: begin
            led[7:0]<=8'b0000_0001;  //
sólo led[1] encendido
            state <= 3'd1;           // saltar a estado 3'd0
           end
     3'd1: begin
            led[7:0]<=8'b0000_0010;  

            state <= 3'd2;           
           end           
     3'd2: begin
            led[7:0]<=8'b0000_0100;
            state <= 3'd3;
           end
     3'd3: begin
            led[7:0]<=8'b0000_1000;
            state <= 3'd4;
           end
     3'd4: begin
            led[7:0]<=8'b0001_0000;
            state <= 3'd5;
           end
     3'd5: begin
            led[7:0]<=8'b0010_0000;
            state <= 3'd6;
           end
     3'd6: begin
            led[7:0]<=8'b0100_0000;
            state <= 3'd7;
           end
     3'd7: begin
            led[7:0]<=8'b1000_0000; // 

            state <= 3'd0;          // volver a estado 0
           end
     default: state <= 3'b0; 
    endcase
   end

  end

endmodule

Máquina de Estado Finita en Verilog - LEDs cambiando automáticamente

Este código es un ejemplo de una máquina de estado en Verilog y puede ser usado en la placa de FPGA  Mojo.

El código enciende uno de los 8 LEDs a la vez en el Mojo. Los LED cambian automáticamente a 1Hz.


module LED_state_machine2(

    input   clk,          
// reloj de 50MHz   
    input   rst_n,
         // entrada de botón reset   
    input   cclk,         
// reloj del microcontrolador AVR
    output  reg[7:0]led,   // salida a 8 LEDs en tarjeta  
    


  // las siguientes conexiones son para el microcontrolador en el Mojo
    output  spi_miso,          // conexiones SPI para AVR
    input   spi_ss,
    input   spi_mosi,
    input   spi_sck,

    output  [3:0] spi_channel, // AVR selección de canal
    input   avr_tx,            // AVR Tx => FPGA Rx
    output  avr_rx,            // AVR Rx => FPGA Tx
    input   avr_rx_busy        // AVR Rx buffer lleno
    );


// sólo para Mojo. asignar alta impedancia si pines no son usados.
assign  spi_miso = 1'bz;
assign  avr_rx = 1'bz;
assign  spi_channel = 4'bzzzz;


reg [25:0] count;      // crea registros para contador 
reg        clk2;
reg  [2:0] state=0;    // crea 8 registros para estados
wire rst = ~rst_n;     // conecta botón de reinicio a registro rst


// divisor de reloj 50MHz a 1Hz
always@(posedge clk)
    begin
        if(count==26'd25000000)  //
cuenta 25M ciclos de clk              begin                  // cambia clk2 a alto o bajo
            count<=0;            
            clk2 <= ~clk2;       
          end
        else
          begin
            count<=count+1;
          end
    end    



// inicio de máquina de estado
always@(posedge clk2) // máquina cambia a 1Hz
 begin                // con transición de clk2
  if(rst)             //
   state <= 3'd0;     // volver a estado 0 si rst es presionado
  else                //
   begin              // comenzar secuencia de máquina de estado
    case(state)
     3'd0: begin
            led[7:0]<=8'b0000_0001;  //
sólo led[1] encendido 
            state <= 3'd1;           // salta a estado 3'd1
           end
     3'd1: begin
            led[7:0]<=8'b0000_0010;  

            state <= 3'd2;           
           end           
     3'd2: begin
            led[7:0]<=8'b0000_0100;
            state <= 3'd3;
           end
     3'd3: begin
            led[7:0]<=8'b0000_1000;
            state <= 3'd4;
           end
     3'd4: begin
            led[7:0]<=8'b0001_0000;
            state <= 3'd5;
           end
     3'd5: begin
            led[7:0]<=8'b0010_0000;
            state <= 3'd6;
           end
     3'd6: begin
            led[7:0]<=8'b0100_0000;
            state <= 3'd7;
           end
     3'd7: begin
            led[7:0]<=8'b1000_0000; 

            state <= 3'd0;          // volver a estado 0
           end
     default: state <= 3'b0; 
    endcase
   end

  end

endmodule

Divisor de Reloj en Verilog

Este código es un ejemplo de un divisor de reloj de 50MHz a 5MHz en Verilog.

Nota: Este código sólo puede dividir frecuencias por números pares (2, 4, 6, 10, etc).  Para dividir frecuencias de reloj por números impares, visita éste articulo.

Los dispositivos lógicos programables operan a velocidades bastante altas. Por ejemplo, el reloj para el FPGA de la tarjeta Mojo opera a 50MHz. Si designáramos un circuito para encender y apagar un LED,  el LED lo haría a 50 o 25 millones de ciclos por segundo (dependiendo del diseño) y por lo tanto, sería imposible de observar con la vista.

Para solucionar esa situación, podemos usar el reloj del FPGA para crear relojes mas lentos. El concepto es simple. El circuito cuenta un número determinado de ciclos de reloj para cambiar una nueva señal a alta o baja. Esta nueva señal sería nuestro nuevo reloj.

La fórmula para calcular el nuevo reloj es simple:

   contador = (reloj_entrante / reloj_nuevo) / 2

entonces, para crear un reloj de 5MHz usando un reloj de 50MHz, nuestro contador usaría 5 ciclos de reloj entrante:

   contador = (50MHz / 5MHz) / 2 = (10) / 2 = 5

En la figura 1, simulamos el divisor de reloj de 50MHz a 5MHz usando Xilinx ISim para mostrar el comportamiento del reloj entrante (clk), el contador (count) y el nuevo reloj (clk2). Nótese que por cada 5 ciclos de clk, clk2 transiciona. La barra amarilla muestra el vector count cuando llega al valor 5 (3'b101) y es seguida por la transición en clk2.

Fig. 1. Simulación de divisor de reloj de 50MHz a 5MHz.

Ejemplo de código:

module clock_divider(
   input           clk,    
// reloj entrante de 50MHz
   output reg      clk2,      // nuevo reloj de 5MHz
    );

reg [3:0] count;

// divisor de reloj 50MHz a 5MHz
always@(posedge clk)
    begin
        if(count==4'd4)      //
cuenta 5 ciclos (0-4) de reloj    
            begin
              count<=0;      // reinicia cuenta a 0
              clk2 <= ~clk2; // transiciona clk2 a alto o bajo
            end
        else
            begin
            count<=count+1;  //  aumenta contador
            end                  end     


Sunday, June 22, 2014

Clock Divider using Verilog

This is a code sample for a 50MHz to 5MHz clock divider using Verilog.

Note: This code will only work to divide the frequencies by an even number (2,4,10, etc).  For a frequency divider by odd numbers, visit this post.

Programmable logic devices (PLD) operate at relatively fast clock speeds. For instance, the clock in the Mojo FPGA runs at 50MHz. If we designed a circuit to make the on-board LEDs blink, they'd do so 50 or 25 million times per second (depending on the design) and therefore, the human eye wouldn't be able to catch it.

To solve that situation we can use the FPGA's input clock to create slower clock signals. The concept is simple. The circuit counts a certain number of clock cycles before setting the new signal as high or low. This new signal would then become our new slower clock.

The math to calculate the number of clk counts for certain frequencies is pretty straight forward:

   counter = (input_clock / new_clock) / 2

thus, if we want to create a 5MHz clock from 50MHz, our counter would use 5 input clock cycles:

   counter = (50MHz / 5MHz) / 2 = (10) / 2 = 5

In figure 1, we simulated our clock divider using Xilinx ISim to show the behavior of the input clock (clk), the counter (count) and the new clock (clk2). Notice that at every 5 clk cycles, clk2 toggles. The yellow tab shows that the count vector is at 5 (3'b101) and is followed by a clk2 transition.



Fig. 1. Behavioral simulation of 50MHz to 5MHz clock divider.


Code sample:

module clock_divider(
   input           clk,    
// 50MHz clock input. reloj de 50MHz
   output reg      clk2,     // new 5MHz clock  
    );

reg [2:0] count;


// clock divider 50MHz to 5MHz

always@(posedge clk)
    begin
        if(count==3'd4)      // counts 5 clk cycles (0 thru 4)

            begin            
              count<=0;        

              clk2 <= ~clk2;   // toggles clk2 to hi or lo
            end
        else
            begin
              count<=count+1; 

            end              
    end     



Finite State-Machine in Verilog - LED changing automatically

This is a code sample for a finite state-machine using Verilog and was tested using the Mojo FPGA board.

The code turns on one of the 8 LED in the Mojo board at a time. The LED transitions automatically at 1Hz.


Code Sample:

module LED_state_machine2(

    input   clk,        
// 50MHz clock input   
    input   rst_n,
       // input from reset button   
    input   cclk,       
// clock input from AVR microcontroller
    output  reg[7:0]led,
// output 8 onboard LEDs  
    

   // all connection below are for the microcontroller in Mojo

    output  spi_miso,          // SPI connections for AVR
    input   spi_ss,
    input   spi_mosi,
    input   spi_sck,

    output  [3:0] spi_channel, // AVR ADC channel select   
    input   avr_tx,            // AVR Tx => FPGA Rx
    output  avr_rx,            // AVR Rx => FPGA Tx
    input   avr_rx_busy        // AVR Rx buffer full
    );

// for Mojo only. these signals should be high-z when not used.


assign  spi_miso = 1'bz;
assign  avr_rx = 1'bz;
assign  spi_channel = 4'bzzzz;


wire    rst = ~rst_n; // make reset active high 
reg  [25:0] count;
reg         clk2;
reg   [2:0] state=0;


// clock divider 50MHz to 1Hz
always@(posedge clk)
    begin
        if(count==26'd25_000_000)    // counts 25M clk cycles and
            begin                    //
toggles clk2 hi or lo
             count<=0;                

             clk2 <= ~clk2;          
            end
        else
            begin
             count<=count+1;
            end
    end    


// beginning of state-machine
always@(posedge clk2)  // state-machine change at clk2 transition
begin 
  if(rst)              // go to state 0 if rst is pressed
    state <= 3'd0;    
  else                 // otherwise start state-machine sequence
   begin             
    case(state)
     3'd0: begin
            led[7:0]<=8'b0000_0001;  // only led[0] is hi
            state <= 3'd1;           // jump to state 3'd1
           end
     3'd1: begin
            led[7:0]<=8'b0000_0010;  

            state <= 3'd2;           
           end            
     3'd2: begin
            led[7:0]<=8'b0000_0100;
            state <= 3'd3;
           end
     3'd3: begin
            led[7:0]<=8'b0000_1000;
            state <= 3'd4;
           end
     3'd4: begin
            led[7:0]<=8'b0001_0000;
            state <= 3'd5;
           end
     3'd5: begin
            led[7:0]<=8'b0010_0000;
            state <= 3'd6;
           end
     3'd6: begin
            led[7:0]<=8'b0100_0000;
            state <= 3'd7;
           end
     3'd7: begin
            led[7:0]<=8'b1000_0000; // back to state 0
            state <= 3'd0;          // volver a estado 0
           end
     default: state <= 3'b0; 
    endcase
   end

  end

endmodule

Saturday, June 21, 2014

Finite State-Machine in Verilog - Using button toggle

This is a code sample for a finite state-machine using Verilog and was tested using the Mojo FPGA board.

The code turns on one of the 8 LED in the Mojo board at a time. The lit LED transitions using the on-board Reset button.


Code Sample:

module LED_state_machine(

    input   clk,    
// 50MHz clock input
    input   nRst,
    // input from reset button
    input   cclk,   
// clock input from AVR microcontroller
    output  reg[7:0]led,  
// output 8 onboard LEDs  
    

    // all connection below are for the microcontroller in Mojo

    output  spi_miso,          // SPI connections for AVR
    input   spi_ss,
    input   spi_mosi,
    input   spi_sck,

    output  [3:0] spi_channel, // AVR ADC channel select   
    input   avr_tx,            // AVR Tx => FPGA Rx
    output  avr_rx,            // AVR Rx => FPGA Tx
    input   avr_rx_busy        // AVR Rx buffer full
    );

// for Mojo only. these signals should be high-z when not used.


assign  spi_miso = 1'bz;
assign  avr_rx = 1'bz;
assign  spi_channel = 4'bzzzz;


reg       rst;     // create registers for button press and state

reg  [3:0]state=0;

always@(posedge clk)
 rst <= ~nRst;     // connects reset button to rst register


//beginning of state-machine
always@(posedge rst)  // state-machine will respond with rst press
begin
    case(state)
        3'd0: begin
                led[7:0]<=8'b0000_0001;  // only led[0] is hi
                state <= 3'd1;           // jump to state 3'd1
              end
        3'd1: begin
                led[7:0]<=8'b0000_0010;  

                state <= 3'd2;          
              end           
        3'd2: begin
                led[7:0]<=8'b0000_0100;
                state <= 3'd3;
              end
        3'd3: begin
                led[7:0]<=8'b0000_1000;
                state <= 3'd4;
              end
        3'd4: begin
                led[7:0]<=8'b0001_0000;
                state <= 3'd5;
              end
        3'd5: begin
                led[7:0]<=8'b0010_0000;
                state <= 3'd6;
              end
        3'd6: begin
                led[7:0]<=8'b0100_0000;
                state <= 3'd7;
              end
        3'd7: begin
                led[7:0]<=8'b1000_0000; // back to state 0
                state <= 3'd0;          

              end
     default: state <= 3'b0; 
    endcase
end

endmodule

   

Friday, June 20, 2014

Mojo v2 FPGA Development Board

A couple years ago, I funded a kickstarter for Embedded Micro's Mojo FPGA Development Board, which was promptly delivered a few months later. This development board features:


- Spartan-6 XC6SLX9 FPGA
- 84 digital I/O pins
- 8 analog inputs
- 8 general purpose LEDs
- 1 reset push button
- 1 LED for FPGA configuration status
- Input voltage regulator for 4.8V - 12V (recommended 5V)
- ATmega32U4 microcontroller to configure FPGA, USB interface, and read analog pins
- On-board flash memory for the FPGA configuration file

The microcontroller uses an Arduino compatible bootloader to allow code loading directly from USB or using the Arduino IDE. Embedded Micro also provides a java based code loader to upload .bin files directly to the Spartan-6 using USB, without a Xilinx programmer.

I found this small board pretty convenient for doing some simple FPGA designs. Plus, its ~$80.00 price make it very accessible to hobbyists compared to the majority of Altera or Xilinx based development boards in the market.

Instructions on how to purchase a board, and how to download and install the tool can be found in Embedded Micro's website.

I'll be using my Mojo v2 for most of my FPGA posts in this blog.