Pico Blaze

Author: Scott Gravenhorst

PicoBlaze SCRATCH PAD RAM PREINITIALIZATION (Verilog):

This article describes how to modify the kcpsm3.v module file to pre-initialize the scratchpad RAM to values you define as opposed to the default of all zeroes for all 64 locations.

This can come in handy when you need a table initialized, but are short on instruction space. If done in assembly code, each location would require 2 instructions to initialize, thus to initialize the entire 64 location RAM, you would consume 128 locations.

Since the kcpsm3 module is a source file, we can force it to instantiate it's RAM with values we choose ahead of time and plant in the kcpsm3.v file. This amounts to adding a parameter override clause to the instantiation of each of the 8 RAM64X1S primitives which includes the data to be stored in that bit slice. Unfortunately, we cannot just supply the data as simple bytes because each RAM is only one bit wide and we must supply each single bit (by 64 locations) wide RAM with a single bit wide initializer, 64 bits long, one bit for each of the 64 addressable locations. This requires bit extraction which can be tedious to do by hand.

I have written a C program (gcc) which can do this automatically for you. It requires a kcpsm3.v file as well as a file containing the initialization values for all 64 eight bit wide locations of the RAM in the form:

aa=dd

where aa is the RAM address in hex (00 through 3F) and dd is the hex data byte to use for initialization for address aa.

All 64 locations MUST be populated, must begin with address 00, must end with address 3F and must be sequential.

The file name for the initialization data should be 'spRAMdata' and should reside in the project directory. kcpsm3.v should also reside there.

Change to the project directory and run the program 'bitex'. bitex does the bit extraction from spRAMdata. kcpsm3.v is read and a modified version is written as kcpsm3.v.new in the project directory. Rename kcpsm3.v.new to kcpsm3.v and then recompile your project and the new values should be apparent to the application.

Note1: This C source was written for a Linux environment capable of handling 64 bit integer type "unsigned long long". It was tested with Fedora Core 5 Linux.

Note2: The kcpsm3.v module source code contains defparam statements which look syntax correct and should initialize the scratch pad RAM. However, using WebPACK ISE 8.1i, I could not get this to work. So the bitex program below does two things: 1) calculate bit extraction and create implicit initializer code using #() format and 2) removes the defparam statements meant to initialize the RAM.

C source code for bitex.c:


// bitex.c
// Scott R. Gravenhorst 2007-02-04
// do bit extraction from file ./spRAMdata and modify kcpsm3.v
// with initialization code for scratch pad RAM.

#include <stdio.h>
#include <string.h>

#define BUFSIZE 1024

int main ( int argc, char *argv[] )
{
FILE *fi, *fo;
char filename[1024] = {"./spRAMdata"};
char buf[BUFSIZE];
char *p;
char data[8][32];
unsigned int bit, i, val;
unsigned int mask = 1;
unsigned long long n;

for ( bit=0; bit<8; bit++ )
  {
  fi = fopen( filename, "r" );
  for ( n=0LL,i=0; i<64; i++ )            // for entire address range
    {
    fgets( buf, BUFSIZE, fi );      // get line from file
    p = strtok( buf, "=" );         // toss address...
    p = strtok( NULL, "=" );        // get data byte value
    sscanf( p, "%X", &val );        // convert ASCII hex to binary
    n = n >> 1;                     // shift bits right to make room in MSB
    n = n + ( ((val & mask)!=0) ? 0x8000000000000000LL : 0LL );  // add in new MSB
    }
  sprintf( data[bit], "%.16llX", n );
  mask = mask << 1;                 // advance bit to extract
  fclose( fi );
  }

///////////////////
// ASCII hex data generated by bit extraction from input file now resides in array data[]
// Now read through kcpsm3.v and add new initialization data

fi = fopen( "./kcpsm3.v", "r" );
fo = fopen( "./kcpsm3.v.new", "w" );

i = 0;
while ( fgets( buf, BUFSIZE, fi ) != NULL )
  {
  if ( strstr( buf, "RAM64X1S" ) == NULL )
    {
    // The kcpsm3.v module comes with defparam statements that are meant to initialize the SP RAM,
    // but they don't work with WebPACK ISE (8i).  Therefore, this program removes them to prevent
    // confusing the compiler.
    if ( strstr( buf, "defparam memory_bit_" ) == NULL )  fprintf( fo, "%s", buf );
    }
  else
    {
    fprintf( fo, " RAM64X1S #(.INIT(64'h%s)) memory_bit_%d (\n", data[i], i );
    i++;
    }
  }
fclose( fi );
fclose( fo );
}