New Horizons






<< August 2007 >>
Sun Mon Tue Wed Thu Fri Sat
 01 02 03 04
05 06 07 08 09 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31


Table of content

New Horizons
What's new
Starting a blog
Writing a blog
I got a job

SystemC
SystemC from scratch. Part 1
SystemC from scratch. Part 2
SystemC from scratch. Part 3

ASIC/FPGA Design
Table of content
Index
FPGA design from scratch. Part 1
FPGA design from scratch. Part 2
FPGA design from scratch. Part 3
FPGA design from scratch. Part 4
FPGA design from scratch. Part 5
FPGA design from scratch. Part 6
FPGA design from scratch. Part 7
FPGA design from scratch. Part 8
FPGA design from scratch. Part 9
FPGA design from scratch. Part 10
FPGA design from scratch. Part 11
FPGA design from scratch. Part 12
FPGA design from scratch. Part 13
FPGA design from scratch. Part 14
FPGA design from scratch. Part 15
FPGA design from scratch. Part 16
FPGA design from scratch. Part 17
FPGA design from scratch. Part 18
FPGA design from scratch. Part 19
FPGA design from scratch. Part 20
FPGA design from scratch. Part 21
FPGA design from scratch. Part 22
FPGA design from scratch. Part 23
FPGA design from scratch. Part 24
FPGA design from scratch. Part 25
FPGA design from scratch. Part 26
FPGA design from scratch. Part 27
FPGA design from scratch. Part 28
FPGA design from scratch. Part 29
FPGA design from scratch. Part 30
FPGA design from scratch. Part 31
FPGA design from scratch. Part 32
FPGA design from scratch. Part 33
FPGA design from scratch. Part 34
FPGA design from scratch. Part 35
FPGA design from scratch. Part 36
FPGA design from scratch. Part 37
FPGA design from scratch. Part 38
FPGA design from scratch. Part 39
FPGA design from scratch. Part 40
FPGA design from scratch. Part 41
FPGA design from scratch. Part 42
FPGA design from scratch. Part 43
FPGA design from scratch. Part 44
FPGA design from scratch. Part 45
FPGA design from scratch. Part 46
FPGA design from scratch. Part 47
FPGA design from scratch. Part 48
FPGA design from scratch. Part 49
FPGA design from scratch. Part 50
Links
Acronyms and abbreviations
XCell Journals
CAD
A hardware designer's best friend
Zoo Design Platform
Linux
Installing Ubuntu Linux on a MacBook
Customizing Ubuntu Linux 1
Customizing Ubuntu Linux 2
Upgrading to Ubuntu 7.04
Install Ubuntu 7.04 with VMware
Making the virtual machine run faster
Ubuntu Links
A processor benchmark
Mac
Porting a Unix program to Mac OS X
Fixing a HyperTerminal in Mac OS X
A dream come true
Wireless freedom
Running
The New York City Marathon
Skiing/Skating
Kittelfjäll Lappland
Tour skating in Sweden and around the world
Top
Introduction
SSSK
Wild skating
Tour day
Safety equipment
A look at the equipment you need
Skate maintenance
Calendar
Links
Books, photos, films and videos
Weather forecasts
Travel
38000 feet above see level
A trip to Spain
Florida the sunshine state


Example Files
Verilog Testbench Body
Verilog Testcase
Verilog Setup
Simulation Result File
Simulation Report File




Photo Albums
Seaside Florida
Ronda Spain
Sevilla Spain
Cordoba Spain
Alhambra Spain
Kittelfjäll Lapland
Landsort Art Walk
Skating on thin ice


Favorites
Adventures in ASIC
ChipHit
Computer History Museum
Community of Sweden
DeepChip
Design & Reuse
Dilbert
EDA Cafe
EDA DesignLine
Embedded.com
EmbeddedRelated.com
FPGA Arcade
FPGA Blog
FPGA Central
FPGA Journal
FPGA World
MacApper
Mac geekery
Mac 2 Ubuntu
Get Perpendicular
Programmable Logic DesignLine
History of Linux
OpenCores
ORSoC
Simplehelp
SOCcentral
World of ASIC



New York City Marathon




If you want to be updated on this weblog Enter your email here:



rss feed



 
Aug 12, 2007
FPGA design from scratch. Part 39
Fixing our software device driver

Let's modify our template files and start with the .tcl file.

etc_v2_1_0.tcl

The .tcl script file copies the parameters we specify to the xparameters.h and xextc_g.c files during library generation. It looks like this after modifications.

proc generate {drv_handle} {
  set level [xget_value $drv_handle "PARAMETER" "level"]
  xdefine_include_file $drv_handle "xparameters.h" "XEtc" "NUM_INSTANCES" "MEM_BANK0_BASE_ADDR" "MEM_BANK0_HIGH_ADDR" "MEM_BANK1_BASE_ADDR" "MEM_BANK1_HIGH_ADDR" "REGISTER_BASE_ADDR" "REGISTER_HIGH_ADDR" "DEVICE_ID" "C_INTERRUPT_PRESENT"
  xdefine_config_file $drv_handle "xetc_g.c" "XEtc"  "DEVICE_ID" "MEM_BANK0_BASE_ADDR" "MEM_BANK1_BASE_ADDR" "REGISTER_BASE_ADDR" "C_INTERRUPT_PRESENT"
}

This is the result taken from the xparameters.h file.

/* Definitions for driver ETC */
#define XPAR_XETC_NUM_INSTANCES 1

/* Definitions for peripheral ETC_0 */
#define XPAR_ETC_0_MEM_BANK0_BASE_ADDR 0x42a08000
#define XPAR_ETC_0_MEM_BANK0_HIGH_ADDR 0x42a08fff
#define XPAR_ETC_0_MEM_BANK1_BASE_ADDR 0x42a09000
#define XPAR_ETC_0_MEM_BANK1_HIGH_ADDR 0x42a09fff
#define XPAR_ETC_0_REGISTER_BASE_ADDR 0x71A00000
#define XPAR_ETC_0_REGISTER_HIGH_ADDR 0x71A0001F
#define XPAR_ETC_0_DEVICE_ID 0
#define XPAR_ETC_0_INTERRUPT_PRESENT 0

etc_v2_1_0.tcl.mdd

The .mdd file looks like this.
The "copyfiles" line instructs the EDK tools to copy the source files into the user's project directory and compile them from there.

OPTION psf_version = 2.1;

BEGIN driver etc

  OPTION supported_peripherals = (ETC_0);
  OPTION driver_state = ACTIVE;
  OPTION depends = (common_v1_00_a);
  OPTION copyfiles = all;

 BEGIN INTERFACE linux
 END INTERFACE

 BEGIN ARRAY interrupt_handler
 END ARRAY

END driver



Makefile

In the Makefile we have to add all header file under INCLUDEFILES. This will copy the header files to the directory include during library generation.

COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a

RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}

INCLUDEFILES=xetc.h xetc_l.h xetc_i.h

LIBSOURCES=*.c
OUTS = *.o


xetc_g.c


The xetc_g.c is automatically generated by Libgen. Here is the configuration table taken from the xetc_g.c file.


/*
* The configuration table for devices
*/

XEtc_Config XEtc_ConfigTable[] =
{
    {
        XPAR_ETC_0_DEVICE_ID,
        XPAR_ETC_0_MEM_BANK0_BASE_ADDR,
        XPAR_ETC_0_MEM_BANK1_BASE_ADDR,
        XPAR_ETC_0_REGISTER_BASE_ADDR,
        XPAR_ETC_0_INTERRUPT_PRESENT
    }

xetc.h

The following type definition are modified to match with the configuration table shown above.


/**
 * This typedef contains configuration information for the device.
 */
typedef struct
{
    Xuint16  DeviceId;          /* Unique ID  of device */
    Xuint32  Mem0_BaseAddress;  /* Memory bank0 base address */
    Xuint32  Mem1_BaseAddress;  /* Memory bank1 base address */
    Xuint32  Reg_BaseAddress;   /* Register bank base address */
    Xboolean InterruptPresent;  /* Are interrupts supported in h/w */
} XEtc_Config;

/**
 * The XEtc driver instance data. The user is required to allocate a
 * variable of this type for every ETC device in the system. A pointer
 * to a variable of this type is then passed to the driver API functions.
 */
typedef struct
{
    Xuint32  Mem0_BaseAddress;  /* Memory bank0 base address */
    Xuint32  Mem1_BaseAddress;  /* Memory bank1 base address */
    Xuint32  Reg_BaseAddress;   /* Register bank base address */
    Xuint32  IsReady;           /* Device is initialized and ready */
    XEtc_Config *ConfigPtr;     /* Pointer to the configuration */
} XEtc;

xetc_l.h

For the lowest level we only need to provide register read an write functions. We will use the Xilinx standard routines XIo_Out32 and XIo_in32 to give us these functions.

/****************************************************************************/
#define XEtc_mWriteReg(BaseAddress, RegOffset, Data) XIo_Out32((BaseAddress) + (RegOffset), (Xuint32)(Data))

/****************************************************************************/
#define XEtc_mReadReg(BaseAddress, RegOffset)  XIo_In32((BaseAddress) + (RegOffset))

The XIo_Out32 and XIo_In32 are defined in the header file xio.h found in the include directory.

* Performs an input operation for a 32-bit memory location by reading from the
* specified address and returning the value read from that address.
*
* @param    InputPtr contains the address to perform the input operation at.
*
* @return   The value read from the specified input address.
*

#define XIo_In32(InputPtr)  (*(volatile Xuint32 *)(InputPtr))


* Performs an output operation for a 32-bit memory location by writing the

* specified value to the the specified address.
*
* @param    OutputPtr contains the address to perform the output operation at.
* @param    Value contains the value to be output at the specified address.
*
* @return   None.
*

#define XIo_Out32(OutputPtr, Value) (*(volatile Xuint32 *)((OutputPtr)) = (Value))


Writing an application program

We will start out writing a low level application program only using the read/write functions. Here is an example:

//$$INCLUDE
/*************************************************************************/
/*                                                                       */
/*                     I N C L U D E   H E A D E R   F I L E S           */
/*                                                                       */
/*************************************************************************/

#include "xparameters.h"
#include "xetc.h"
#include "xetc_l.h"
#include "xutil.h"
#include <stdio.h>


//$$DEFINE
/*************************************************************************/
/*                                                                       */
/*                       D E F I N E   C O N S T A N T S                 */
/*                                                                       */
/*************************************************************************/

// The following constant maps to the name of the hardware instances that
// were created in the EDK XPS system.

#define  ETC_REG_BASEADDR      XPAR_ETC_0_REGISTER_BASE_ADDR
 
// The following parameters are used to setup the ETC
#define  ENABLE_INTERRUPT      0X1000
#define  DISABLE_INTERRUPT     0X0
#define  ENABLE_LOOP_MODE      0x800
#define  DISABLE_LOOP_MODE     0x0
#define  SKIP_TDO_SHIFTIR      0x200
#define  SKIP_TDO_SHIFTDR      0x400
#define  DISABLE_SINGLE_STEP   0x0
#define  ENABLE_SINGLE_STEP    0x100
#define  DISABLE_TCK           0x0
#define  ENABLE_TCK            0x80
#define  CLOCK_RATE_DIV_BY_4   0x0
#define  CLOCK_RATE_DIV_BY_8   0x10
#define  CLOCK_RATE_DIV_BY_16  0x20
#define  CLOCK_RATE_DIV_BY_32  0x30
#define  CLOCK_RATE_DIV_BY_64  0x40
#define  EXTERNAL_TEST         0x8

#define  START_ETC             0x1
#define  STOP_ETC              0x0

//$$FUNCTIONS
/*************************************************************************/
/*                                                                       */
/*                       D E F I N E   F U N C T I O N S                 */
/*                                                                       */
/*************************************************************************/

void usleep(unsigned int useconds)
{
  int i,j;
  for (j=0;j<useconds;j++)
    for (i=0;i<26;i++) asm("nop");
}

//$$ETC TEST PROGRAM
/*************************************************************************/
/*                                                                       */
/*                     E T C   T E S T  P R O G R A M                    */
/*                                                                       */
/*************************************************************************/


// Define testprogram

// TestResetKeepingTrstzLow (10);
// LoadInstruction(INSTRUCTION_LENGTH,IDCODE);
// ReadWriteDataRegister(IdentificationRegLen+20,{{IdentificationRegLen{1'b0}},20'b1110011101});
// SetExpectedData(IdentificationRegLen+20,{20'b1110011101,{IdentificationRegLen{1'bx}}});
// EndOfTestProgram;

 Xuint32 TestProgram[] = {

     
  0x800000a1,
  0xc0000043,
  0x00000002,
  0xc0340004,
  0x4000039d,
  0x00000000,
  0x8000000c };
 
  int  ProgramSize =  7;


//$$MAIN
/*************************************************************************/
/*                                                                       */
/*                        M A I N   P R O G R A M                        */
/*                                                                       */
/*************************************************************************/


int main(void) {

    int               i;
    Xuint32  StatusReg;
   
    print("Load test program ");
   
    // Load test program to test program RAM
    for (i = 0; i < ProgramSize; i++) {
           XEtc_mWriteReg(XPAR_ETC_0_MEM_BANK0_BASE_ADDR, i*4, TestProgram[i]);   
    };

    // Write to control register
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_CONTROL_REG_OFFSET,
        DISABLE_INTERRUPT +
        DISABLE_LOOP_MODE +
        SKIP_TDO_SHIFTIR +
        DISABLE_SINGLE_STEP +
        ENABLE_TCK +
        CLOCK_RATE_DIV_BY_4 +
        EXTERNAL_TEST);
   
    print("Start test ");
    // Start test
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_EXECUTE_REG_OFFSET,
        START_ETC);
 
   // Wait for test to finish
   usleep(4);

    print("Stop test ");
    // Stop test
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_EXECUTE_REG_OFFSET,
        STOP_ETC);
       
    // Stop TCK
    XEtc_mWriteReg(ETC_REG_BASEADDR, XETC_CONTROL_REG_OFFSET,
        DISABLE_INTERRUPT +
        DISABLE_LOOP_MODE +
        SKIP_TDO_SHIFTIR +
        DISABLE_SINGLE_STEP +
        DISABLE_TCK +
        CLOCK_RATE_DIV_BY_4 +
        EXTERNAL_TEST);

   // Read status register
   print("Read status register ");  
   StatusReg = XEtc_mReadReg(ETC_REG_BASEADDR, XETC_STATUS_REG_OFFSET);
   xil_printf("Status reg : %x ",StatusReg);


   return 0;
   
    }

Print statements

To save memory space we don't use the standard print routines like printf. Instead we use <xil_printf>and <print>.  


Printout from program

After compiling and linking the program we download it to our design. The program starts and prints out the following text:

Load test program
Start test
Stop test
Read status register
Status reg : 3464


The value in the status register tells us that the testprogram ran successfully. We have written our first application program to drive the ETC. One more milestone reached.


Generate HDL simulation files

We can use the following command from the commandline to generate the HDL simulation files.

==> cd /home/svenand/root/projects/ETC/xps
==> simgen -f simgen.opt

Here is the output:

Simulation Model Generator
Xilinx EDK 9.1.01 EDK_J_SP1.3
Copyright (c) 1995-2007 Xilinx, Inc.  All rights reserved.
Command Line: simgen -p xc4vfx12ff668-10 -lang vhdl -pe microblaze_0
SDK_projects/ETC_system_program/Debug/ETC_system_program.elf -mixed yes -s ncs
-tb -X /home/svenand/root/projects/ETC/verification/database/ncsim/macrolib/ -E
/home/svenand/root/projects/ETC/verification/database/ncsim/edklib/ -m
behavioral ETC_system.mhs

MHS file              : /home/svenand/root/projects/ETC/xps/ETC_system.mhs
Language (-lang)      : VHDL
Simulation Model (-m) : Behavioral
Simulator (-s)        : NcSim (NCS)
Part (-p) [ family ]  : xc4vfx12ff668-10 [ virtex4 ]
Output directory (-od): /home/svenand/root/projects/ETC/xps/

Edklib (-E) :
/home/svenand/root/projects/ETC/verification/database/ncsim/edklib/
Xlib (-X)   :
/home/svenand/root/projects/ETC/verification/database/ncsim/macrolib/

..........

Analyzing file
/home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf...
INFO:MDT - BRAM lmb_bram will be initialized with ELF of processor microblaze_0
Running Data2Mem with the following command:
data2mem -bm ETC_system_sim.bmm  -bd
/home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf tag microblaze_0  -u  -o u tmpucf.ucf

Generating simulator compile script ...

Generating the BRAM initialization file

If we only changed the application program file (.elf) we don't have to generate all the HDL simulation files. We only need the BRAM initialization file:  ETC_system_init.vhd. This file can generated in these two steps:
  1. Use data2mem to convert the .elf file to a .ucf file
  2. Use ucf2vhdl.pl to convert the .ucf file to a .vhdl file
==> cd /home/svenand/root/projects/ETC/xps/simulation/behavioral

==> data2mem -bm ETC_system_sim.bmm  -bd /home/svenand/root/projects/ETC/xps/SDK_projects/ETC_system_program/Debug/ETC_sy
stem_program.elf tag microblaze_0  -u  -o u tmpucf.ucf

==> xilperl /home/svenand/cad/edk91i/bin/lin/ucf2vhdl.pl tmpucf.ucf ETC_system_init.vhd ETC_system ETC_system_conf vhdl

Running a simulation

Here is the same application program running in a simulation.




Top  Next  Previous



Posted at 08:56 am by svenand

 

Leave a Comment:

Name


Homepage (optional)


Comments




Previous Entry Home Next Entry