#include #include #include #include #define ARCH_NAME "data" #define ENT_NAME "ram" #define JTAG_ADDR_WIDTH 16 // -------------------------------------------------------------- void basename(char *pSrc, char *pDst) { int i, size; size = strlen(pSrc); while(pSrc[size] != '.') size--; for (i=0; i < size; i++) pDst[i] = pSrc[i]; pDst[i] = 0; } int SaveRAM_TCL(char *pFilenameIn, char *pFilenameOut, char *pArchName, char *pEntName, int nbits_addr, int nbits_data) { FILE *pFileIn, *pFileOut; long start, end; int i, word, word_addr, filesize, romsize; char binstr_addr[33]; char binstr_data[33]; char tpl[] = {"# ---------------------------------------------------------------------\n# For Chipscope 9.1\n# ---------------------------------------------------------------------\n# Source JTAG/TCL frame work\ncd $env(CHIPSCOPE)\\\\bin\\\\nt\nsource csejtag.tcl\n\nnamespace import ::chipscope::*\n\n# Platform USB Cable\nset PLATFORM_USB_CABLE_ARGS [list \"port=USB2\" \"frequency=6000000\"]\n# frequency=\"24000000 | 12000000 | 6000000 | 3000000 | 1500000 | 750000\"\n\n# Create session\nset handle [::chipscope::csejtag_session create 0]\n\n# Open JTAG and lock\nset open_result [::chipscope::csejtag_target open $handle $CSEJTAG_TARGET_PLATFORMUSB 0 $PLATFORM_USB_CABLE_ARGS]\nset lock_result [::chipscope::csejtag_target lock $handle 1000]\n\nset devlist [::chipscope::csejtag_tap autodetect_chain $handle $CSEJTAG_SCAN_DEFAULT]\n\n# Get Device ID\nset devtype \"Virtex-4SX\"\nset devid 2\nset irlength [::chipscope::csejtag_tap get_irlength $handle $devid]\nset idcode [::chipscope::csejtag_tap get_device_idcode $handle $devid]\n\nset CSE_OP $CSEJTAG_SHIFT_READWRITE\nset CSE_ES $CSEJTAG_RUN_TEST_IDLE\n\n# Write Program\n"}; pFileIn = fopen(pFilenameIn, "rb"); if (!pFileIn) { fprintf(stderr, "Error opening file %s\n", pFilenameIn); return 1; } pFileOut = fopen(pFilenameOut, "wb"); if (!pFileOut) { fprintf(stderr, "Error opening file %s\n", pFilenameOut); return 1; } fseek(pFileIn, 0, SEEK_SET); start = ftell(pFileIn); fseek(pFileIn, 0, SEEK_END); end = ftell(pFileIn); fseek(pFileIn, 0, SEEK_SET); filesize = (end-start); romsize = (int)pow(2, nbits_addr+2); // ------------------------------------------------------------------------- // Header // ------------------------------------------------------------------------- fputs(tpl, pFileOut); // ------------------------------------------------------------------------- // ROM part // ------------------------------------------------------------------------- fprintf(pFileOut, "# Assembled from %s\n", pFilenameIn); fprintf(pFileOut, "# ---------------------------------------------------------------\n"); fprintf(pFileOut, "# Shift the USER2 Instruction (b1111000011) into the Instruction Register of FPGA\n"); fprintf(pFileOut, "# User 2\n"); fprintf(pFileOut, "set result [::chipscope::csejtag_tap shift_device_ir $handle $devid $CSE_OP $CSE_ES 0 $irlength \"3C3\"]\n\n"); word_addr = 0; for (i=0; i < filesize; i += sizeof(int)) { fread(&word, 1, sizeof(int), pFileIn); fprintf(pFileOut, "::chipscope::csejtag_tap shift_device_dr $handle $devid $CSE_OP $CSE_ES 0 %d \"%4.4X%8.8X\"\n", nbits_data + JTAG_ADDR_WIDTH, word_addr, word); word_addr++; } fprintf(pFileOut, "\n"); // ------------------------------------------------------------------------- // Trailer // ------------------------------------------------------------------------- fprintf(pFileOut, "::chipscope::csejtag_target unlock $handle\n"); fprintf(pFileOut, "::chipscope::csejtag_target close $handle\n"); fprintf(pFileOut, "::chipscope::csejtag_session destroy $handle\n"); fprintf(pFileOut, "exit\n"); return 0; } int main(int argc, char *argv[]) { char *pFilenameIn; char name_prj[1024]; char name_rom_tcl[1024]; FILE *pFileIn; int filesize, romsize, nbits_addr, nbits_data; long start, end; int word, i; if (argc < 2) { fprintf(stderr, "Usage: romgen \n"); return 1; } pFilenameIn = argv[1]; if (argc == 3) nbits_addr = atoi(argv[2]); basename(pFilenameIn, name_prj); sprintf(name_rom_tcl, "%s.tcl", name_prj); SaveRAM_TCL(pFilenameIn, name_rom_tcl, ARCH_NAME, ENT_NAME, nbits_addr, 32); return 0; }