Home > Uncategorized > Spartan 6 Learner's board up and running

Spartan 6 Learner's board up and running

November 28th, 2015

Vikas Shukla -November 28, 2015

Two months ago the Spartan 6 Learner's board PCB was released for prototype manufacturing. It was supposed to be released in October. But few things came up in between and after a delay of a month, the first prototype is up and running. And this is the subject of this post.


We are able to power up the board and are able to program it using Xilinx ISE tool. We started with a simple code that will take in the Switch SW3 and will display the LED2 when the switch is pressed. A simple verilog code is here

module LED_Button
input button_sw3,
output led2

assign led2 = ~button_sw3;


It also required the ucf file for the two pins used in the code

NET "led2" LOC = P131;
NET "button_sw3" LOC = P126;

Here is a video of board running the above code.

This code will verify both the Switches and both the LEDs

module LED_Buttom
input button_sw2, button_sw3,
output led1,led2

assign led1 = button_sw2; 
assign led2 = button_sw3;

The associated ucf file is

NET "led2" LOC = P131;
NET "button_sw3" LOC = P126;
NET "led1" LOC = P127;
NET "button_sw2" LOC = P124;

The board can be powered either by USB or by a Wall mount power supply that can take in wide range of input from 4.5V to 18V. The power supply from USB comes handy when you wish to debug your board while being connected with your laptop.

The board was built manually, obviously there was some scope of error. For example here is an example program that I tried to test the three seven segment display.

module LED_Buttom
input button_sw3,
output select_7seg3, sega,segb,segc,segd,sege,segf,segg,segdot

assign select_7seg3 = button_sw3;
assign sega = button_sw3;
assign segb = button_sw3;
assign segc = button_sw3;
assign segd = button_sw3;
assign sege = button_sw3;
assign segf = button_sw3;
assign segg = button_sw3;
assign segdot = button_sw3;

With the following section of ucf file


NET "button_sw3" LOC = P126;
NET "sega" LOC = P5;
NET "segb" LOC = P141;
NET "segc" LOC = P16;
NET "segd" LOC = P21;
NET "sege" LOC = P22;
NET "segf" LOC = P2;
NET "segg" LOC = P15;
NET "segdot" LOC = P17;

//NET "select_7seg1" LOC = P12; 
//NET "select_7seg2" LOC = P144;
NET "select_7seg3" LOC = P142;

It did work, however, the segments c and d did not work as ( corresponding to resistors R10 and R12 in the schematics) you can see in the picture below ( likely a manual assembly error).


The DIP switches were verified by making each segment of the 7 segment LED turn on and off based upon which switch is turned on or off. The following is the section of the ucf file for the 8 pins of the DIP switch.

NET "dip1" LOC = P23;
NET "dip2" LOC = P24;
NET "dip3" LOC = P26;
NET "dip4" LOC = P27;
NET "dip5" LOC = P29;
NET "dip6" LOC = P30;
NET "dip7" LOC = P32;
NET "dip8" LOC = P33;

The following code will test the 50 MHz oscillator on the board by blinking and LED.

module clk_div (

input clk,
output  led2    

    reg [32:0] counter;
    reg state;
    assign led2 = state;
    always @ (posedge clk)
        counter <= counter + 1;
        state <= counter[26]; // Changes when MSB changes


Of course you will need to assign 50 MHz clock input to Pin 55 as in the following ucf file.

NET "LED2" LOC = P131; //LED2
NET "clk" LOC = P55; // clk

The video of the LED blinking example

Update 11/29/2015

After touching up the 7 Segment area on the board, it was confirmed that the assembly was the issue.


Serial Port

A nice feature of the learner's board is its ability to communicate with the your computer on UART made possible by the in built USB to UART chip PL2303. You need putty and a USB port on your computer to test the Serial Port. The following code will send an ascii letter on the Serial Port every time switch SW3 is pressed. The switch edge level detection is imported from this post . The serial port code is borrowed from the stackexchange post here ( of course we corrected the stop bit thing mentioned in the post).

module uart_on_spartan6(input clk, reset, button_sw3 , output ser);

reg start;
reg [7:0] data;
reg [14:0] clockdiv;

// 9600 baud generator

always @(posedge clk) 
    if (clockdiv == 5207) 
        clockdiv <= 0;
        clockdiv <= clockdiv + 1;

wire serclock = (clockdiv == 0);

reg [3:0] state;

always @(posedge clk)
   case (state)
        4'b0000: if (start) state <= 4'b0001;
        4'b0001: if (serclock) state <= 4'b0010;    // Start bit
        4'b0010: if (serclock) state <= 4'b0011;    // Bit 0
        4'b0011: if (serclock) state <= 4'b0100;    // Bit 1
        4'b0100: if (serclock) state <= 4'b0101;    // Bit 2
        4'b0101: if (serclock) state <= 4'b0110;    // Bit 3
        4'b0110: if (serclock) state <= 4'b0111;    // Bit 4
        4'b0111: if (serclock) state <= 4'b1000;    // Bit 5
        4'b1000: if (serclock) state <= 4'b1001;    // Bit 6
         4'b1001: if (serclock) state <= 4'b1010;   // Bit 7
        4'b1010: if (serclock) state <= 4'b0000;    // Stop bit
        default: state <= 4'b0000;                  // Undefined, skip to stop

reg outbit;

always @(posedge clk)
    case (state)
         4'b0000: outbit <= 1;              // idle
         4'b0001: outbit <= 0;              // Start bit
         4'b0010: outbit <= data[0];        // Bit 0
         4'b0011: outbit <= data[1];        // Bit 1
         4'b0100: outbit <= data[2];        // Bit 2
         4'b0101: outbit <= data[3];        // Bit 3
         4'b0110: outbit <= data[4];        // Bit 4
         4'b0111: outbit <= data[5];        // Bit 5
         4'b1000: outbit <= data[6];        // Bit 6
         4'b1001: outbit <= data[7];        // Bit 7
         4'b1010: outbit <= 1;          // Stop bit
			 default: outbit <= 1;          // Bad state output idle

// Output register to pin
assign ser = outbit;

// Test by outputting a letter 'd'

	reg  delay_reg  ;
	 always @(posedge  clk,  negedge  reset)
    if  ( reset == 0)
	 data <= 100; // corressponds to letter d
    delay_reg  <=  0;
	 start <=0;
    delay_reg  <=  button_sw3 ;
	 start  <=  (delay_reg)  &  (~button_sw3);

Of course, we also used the switch SW2 for reset. The ucf file used for this project is here

NET "clk" LOC = P55; // clk
NET "ser" LOC = P80; // Data Transmission from FPGA to PL2303
NET "button_sw3" LOC = P126;
NET "reset" LOC = P124;

Booting from the Flash

Once you have tested the board with your code, you may want to program the flash, so the board can boot from it when powered on. We verified that it did work. It will be the subject of another separate post.

The leaves us with the following things still to be verified.

3. SPI Bus A/D Converter

There are open source code for I2C Bus, but we may be writing a deprecated I2C code, which will possible write a defined byte on a given address on the I2C EEPROM. And then possibly a read code which will read read from the I2C and display on the 7 segment display.

Update 12/05/2015

We started putting together the material for this eval board here and the steps to programming the SPI FLash here


  1. No comments yet.
  1. No trackbacks yet.