在VHDL中读取.hex文件

时间:2014-07-29 21:23:10

标签: file-io vhdl

我正在尝试使用以下VHDL代码段读取intel .hex文件。我的合成器有一个问题,那就是应该在一行开头检查和丢弃':'字符的代码部分。综合工具给出了此错误“调用无身体的过程”(标有注释的行)。我从未见过这个错误,也不知道这意味着什么。是否有解决此错误的方法(或者放弃':'字符的替代方法)?

function Load_Data(constant x: in integer) return ROM_Data is
    use std.textio.all;
    use ieee.std_logic_textio.all;

    file ROMFILE: TEXT open READ_MODE is "IIU_Code.hex";

    variable newline: line;
    variable newchar: character;
    variable newbyte: std_logic_vector(7 downto 0);
    variable newword: std_logic_vector(15 downto 0);

    variable NextAddr, ByteCount: integer;
    variable NewROM: ROM_Data := (others => (others => '0'));
    variable valid: boolean := True;
begin
    while (valid) loop
        readline(ROMFILE, newline);
        read(newline,newchar,valid);                      --ERROR HERE!!!
        if (newchar = ':') and (valid = True) then
            hread(newline,newbyte);
            ByteCount := to_integer(unsigned(newbyte));
            hread(newline,newword);
            NextAddr := to_integer(unsigned(newword));
            hread(newline,newbyte);
            if newbyte = X"01" then     --check for EOF marker
                valid := False;
            end if;
            for i in 1 to ByteCount loop
                hread(newline,newbyte);
                NewROM(NextAddr) := newbyte;
                NextAddr := NextAddr + 1;
            end loop;
        end if;
    end loop;

    file_close(ROMFILE);
    return NewROM;
end;

1 个答案:

答案 0 :(得分:1)

代替尝试强制合成从文件初始化ROM我已经知道编写将模型数据转换为常量的C程序,在这种情况下通过生成实体/体系结构对:

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

#define MAX_VECTOR 512

void rom_header (rom_name,array_size)
char *rom_name;
int array_size;
{
    printf("library ieee;\nuse ieee.std_logic_1164.all;\n");
    printf("\nentity %s is\n    port (\n",rom_name);
    printf("\tindex:\t\tin     integer range 0 to %d;\n",array_size*8-1);
    printf("\tOE:\t\tin     std_logic;\n");
    printf("\toutput:\t\tout    std_logic_vector (7 downto 0)\n");
    printf("    );\nend ;\n");
    printf("\narchitecture behave of %s is\n\n",rom_name);
    printf("    subtype bytestring is bit_vector( 7 downto 0);\n");
    printf("    type bytestream is array (0 to %d) of bytestring;\n\n",
        array_size*8-1);
    printf("    constant byte_array:\tbytestream := (\n\t    ");
}

void rom_tail() {
    printf("    begin\n\n");
    printf("    output <= To_StdLogicVector(byte_array(index)) ");
    printf("when OE = '1' else\n");
    printf("              (others => 'Z')                      ");
    printf("when OE = '0' else\n");
    printf("              (others => 'X');\n");
    printf("\n\nend behave;\n\n");
}

int main (argc,argv) 
int argc;
char *argv[];
{
extern char *optarg;
extern int optind, opterr;
extern int getopt();

char *infile;
char key_vector[MAX_VECTOR][16];
char plain_vector[MAX_VECTOR][16];
char cipher_vector[MAX_VECTOR][16];
char testinput[2047];
char testkey[17];
char testplain[17];
char testcipher[17];

int encrypt[MAX_VECTOR];
int i;
int len;
int testcount = 0;
int totalcount = 0;
int linenumber = 0;
int vector = 0;
int encode = 1;

    while ( (i=getopt(argc,argv,"i:")) != -1 )  {
        switch (i) {
        case 'i':
            infile = optarg;
            if((freopen(optarg,"r",stdin)) == NULL) {
                fprintf(stderr,"ERROR:%s, can't open %s for input\n",
                        argv[0],optarg);
                exit(-1);
            }
        break;
        case '?':
            fprintf(stderr,"usage: %s [-i infile] \n",argv[0]);
            fprintf(stderr,"\ngenerates VHDL arrays for DES test vectors:\n");
            fprintf(stderr,"\tcipher_vector.vhdl\n");
            fprintf(stderr,"\tencrypt_vector.vhdl\n");
            fprintf(stderr,"\tkey_vector.vhdl\n");
            fprintf(stderr,"\tplain_vector.vhdl\n");
            exit (-1);
        break;
        }
    }

    while (fgets(testinput,(sizeof testinput) -1, stdin) != NULL ) {

    linenumber++;
    if ( strncmp(testinput,"encrypt",7) == 0) { /* mode = encode */
        encode = 1;
            fprintf(stderr,"%s",testinput);
       }
        else
        if ( strncmp(testinput,"decrypt",7) == 0) { /* mode = decode */
            fprintf(stderr,"%s",testinput);
        encode = 0;
        }
        else 
        if ( strncmp(testinput," ",1) == 0) { /* key, plain & cipher */
        testcount++;
            len = sscanf(testinput,"%s%s%s*", testkey, testplain, testcipher);
            if (len != 3) {
                fprintf(stderr,"ERROR: %s, wrong vector count, line %d\n",
                    argv[0], linenumber);
                exit(-1);
            }
            else if (strlen(testkey) != 16) {
                fprintf(stderr,"ERROR: %s wrong byte count testkey, line %d\n",
                    argv[0],linenumber);
                exit(-1);
        }
            else if (strlen(testplain) != 16) {
                fprintf(stderr,"ERROR: %s wrong byte count testplain, line %d\n",
                    argv[0],linenumber);
                exit(-1);
            }
            else if (strlen(testcipher) != 16) {
                fprintf(stderr,"ERROR: %s wrong byte count testcipher, line %d\n",
                    argv[0],linenumber);
                exit(-1);
            }
            else {
                encrypt[vector] = encode;
                strncpy(   key_vector[vector],   testkey,16);
                strncpy( plain_vector[vector], testplain,16);
                strncpy(cipher_vector[vector],testcipher,16);

                for ( i = 0; i < 16; i++) {
                    if ( !isxdigit(key_vector[vector][i]) ||
                         !isxdigit(plain_vector[vector][i]) ||
                         !isxdigit(cipher_vector[vector][i]) ) {
                    fprintf(stderr,"ERROR: %s, Vector: %d contains nonhex\n",
                        argv[0], vector+1);
                    fprintf(stderr,"\t%s\n",testinput);
                        exit(-1);
                    }
                }
            }
            vector++;
            if (vector == MAX_VECTOR) {
                fprintf(stderr,"%s: Maximum number of vectors = %d\n",
                    argv[0],MAX_VECTOR);
                exit(0);
            }
        }
    else {                                /* nothing but eyewash */
            if ( testcount ) {
        fprintf(stderr," %d test vectors\n",testcount);
                totalcount +=testcount;
                testcount = 0;
            }
        }
    }
    fprintf(stderr," Total: %d test vectors\n",totalcount);

    if (freopen("key_vector.vhdl","w",stdout) == NULL){
        fprintf(stderr,"ERROR: %s can write to key_vector.vhdl\n",argv[0]);
        exit (-1);
    } 
    rom_header("key_vector",totalcount);
    for(vector = 0; vector < totalcount; vector++) {

        for ( i = 0; i <= 15; i++) {
            if ( !(i & 1)) {
                printf("x\"%c",key_vector[vector][i]);
            }
            else {
                if ( i < 15) {
                    printf("%c\",",key_vector[vector][i]);
                }
                else {
                    printf("%c\"",key_vector[vector][i]); // no comma
                }
            } 
        }
        if (vector != totalcount-1) 
            printf(",\n\t    ");
        else
            printf("\n\t);\n");
    }    
    rom_tail();

    if (freopen("plain_vector.vhdl","w",stdout) == NULL){
        fprintf(stderr,"ERROR: %s can write to plain_vector.vhdl\n",argv[0]);
        exit (-1);
    } 
    rom_header("plain_vector",totalcount);
    for(vector = 0; vector < totalcount; vector++) {

        for ( i = 0; i <= 15; i++) {
            if ( !(i & 1)) {
                printf("x\"%c",plain_vector[vector][i]);
            }
            else {
                if ( i < 15) {
                    printf("%c\",",plain_vector[vector][i]);
                }
                else {
                    printf("%c\"",plain_vector[vector][i]); // no comma
                }
            } 
        }
        if (vector != totalcount-1) 
            printf(",\n\t    ");
        else
            printf("\n\t);\n");
    }    
    rom_tail();

    if (freopen("cipher_vector.vhdl","w",stdout) == NULL){
        fprintf(stderr,"ERROR: %s can write to cipher_vector.vhdl\n",argv[0]);
        exit (-1);
    } 
    rom_header("cipher_vector",totalcount);
    for(vector = 0; vector < totalcount; vector++) {

        for ( i = 0; i <= 15; i++) {
            if ( !(i & 1)) {
                printf("x\"%c",cipher_vector[vector][i]);
            }
            else {
                if ( i < 15) {
                    printf("%c\",",cipher_vector[vector][i]);
                }
                else {
                    printf("%c\"",cipher_vector[vector][i]); // no comma
                }
            } 
        }
        if (vector != totalcount-1) 
            printf(",\n\t    ");
        else
            printf("\n\t);\n");
    }    
    rom_tail();

    if (freopen("encrypt_vector.vhdl","w",stdout) == NULL){
        fprintf(stderr,"ERROR: %s can write to encrypt_vector.vhdl\n",argv[0]);
        exit (-1);
    } 
    printf("library ieee;\nuse ieee.std_logic_1164.all;\n");
    printf("\nentity encrypt_vector is\n    port (\n");
    printf("\tindex:\t\tin     integer range 0 to %d;\n",totalcount-1);
    printf("\toutput:\t\tout    std_logic\n");
    printf("    );\nend ;\n");
    printf("\narchitecture behave of encrypt_vector is\n\n");
    printf("    constant bit_array:\tstd_logic_vector(0 to %d) := (\n\t    ",
            totalcount-1);

    i = 0;
    for(vector = 0; vector < totalcount; vector++) {
    printf("'%1d'",encrypt[vector]);i++;
    if ((i == 16) && (vector != totalcount-1)) {
        printf(",\n\t    ");
        i = 0;
    }
    else if (vector == totalcount-1)
        printf("\n\t);\n");
    else
        printf(",");
    }    
    printf("    begin\n\n");
    printf("    output <= bit_array(index);");
    printf("\n\nend behave;\n\n");

    exit (0);
}

您也可以为包甚至子程序执行此操作。

此特定转换软件使用一种有效矢量形式,前面是加密模式开关,并具有第一个列空间,提供正确字符串长度的十六进制值:

# encrypt # 0101010101010101 95F8A5E5DD31D900 8000000000000000 0101010101010101 DD7F121CA5015619 4000000000000000 0101010101010101 2E8653104F3834EA 2000000000000000 0101010101010101 4BD388FF6CD81D4F 1000000000000000 0101010101010101 20B9E767B2FB1456 0800000000000000 0101010101010101 55579380D77138EF 0400000000000000 0101010101010101 6CC5DEFAAF04512F 0200000000000000 #

它是字节宽接口DES芯片的测试向量,在这种情况下仅用于测试平台。没有什么可以阻止你嵌入你想要的东西。

这个小C程序已经很老了但是我相信我最近更新了它会编译和运行,它会吐出几个不同的&#39; vector&#39;测试平台的文件基于值的用途。它希望输入文件以注释行结束(&#39;#&#39;在第一列中),然后是换行符。

因此,此处的消息不会直接计算在您的综合工具上以初始化数据(除非他们使用明确支持的例程处理它)。

请参阅How to synthesis a rom and load initial data into it ?,了解Xilinx中的提示线程,否则请注意您尚未指定目标平台。

<强>附录

提问者即将提供评论中的其他信息,其中自动化软件劝告我们请避免在评论中进行扩展讨论

目标是Microsemi ProASIC3,它还提示再次查看提供的Load_Data函数,其输入参数x不会显示在函数体中。虽然这表明作者可能一直在努力争取阅读文件的上坡限制。

看看Microsemi的网站,我们看到ProASIC3可以有一个嵌入式1K位FLASHROM,它可能是也可能不是有问题的ROM。我从一开始就是ASIC设计师,可以欣赏这些器件的尺寸范围,旨在用于片上系统应用。您希望供应商能够提供有关如何使用FLASHROM的信息。

对于其他ROM目的而不是供应商提供的加载ROM的方法,似乎创建一种嵌入常数数组的合成兼容方法是有序的(类似于C编程示例中所示的内容)。

可编程器件中只读存储器的一个特性是这些值通常作为器件编程的一部分包含在内。