需要与c语言等效的VHDL“;斯特托克“;及;strcmp“;可以在vhdl字符串类型上使用运算符的函数

需要与c语言等效的VHDL“;斯特托克“;及;strcmp“;可以在vhdl字符串类型上使用运算符的函数,vhdl,Vhdl,我正在尝试为vhdl测试台编写一个刺激读取器。它需要读取文本文件中由空格分隔的一个文本命令和两个文本操作数 entity tb is end entity; architecture sim is tb of begin process variable L : line; file STIMFILE : test is in "stim.txt"; variable s1 : string; variable s2

我正在尝试为vhdl测试台编写一个刺激读取器。它需要读取文本文件中由空格分隔的一个文本命令和两个文本操作数

entity tb is
end entity;

architecture sim is tb of
begin

process
    variable L        : line;
    file     STIMFILE : test is in "stim.txt";
    variable s1       : string;
    variable s2       : string;
    variable s3       : string;
begin

    while not endfile(STIMFILE) loop
        readline(STIMFILE, L);

        s1 := strtok(L, "\n\t ");
        s2 := strtok(0, "\n\t ");
        s3 := strtok(0, "\n\t ");

        if (strcmp(s1, "ADDXYZ") = '1') then
            report "ADDXYZ " & s2 & " " & s3;
        end if;
    end loop;

end process;

end architecture;
我将如何在VHDL中实现这一点

到目前为止,我有一个strcmp函数:

FUNCTION strcmp(s1: STRING; s2: STRING)    --string compare 
    RETURN BOOLEAN IS 
  BEGIN 
    IF(s1'LENGTH /= s2'LENGTH) THEN 
      RETURN FALSE; 
    ELSE 
      FOR i IN s1'RANGE LOOP 
        IF(s1(i) /= s2(i)) THEN 
          RETURN FALSE; 
        END IF; 
      END LOOP; 
      RETURN TRUE; 
    END IF; 
  END;   --function strcmp 
ieee库;
使用ieee.std_logic_1164.all;
使用std.textio.all;
包裹包装花式字符串为
--标记化的最大行长度
常数STRTOK_MAX:自然值=200;
过程行2字符串(L:inout行;S:out字符串);
函数是_空间(c:字符)返回布尔值;
函数为_num(c:字符)返回布尔值;
--结构来维护strtok调用之间的状态
strtok_t类型为
记录
str:字符串(1到STRTOK_MAX)--输入字符串
pos:自然--输入字符串迭代器位置
更多:布尔--下一步调用strtok_,直到更多等于错误停止
tok:字符串(1到STRTOK_MAX)--令牌字符串值
len:自然的--令牌字符串长度
有效值:布尔值--令牌字符串有效
误差:自然--令牌字符串出错,例如:截断
结束记录;
--返回长度为n的字符串,如果最初小于n,则用nul填充
函数strpad(n:natural;x:string;rm_comment:boolean)返回字符串;
--使用未解析的字符串初始化strtok结构
函数strtok_init(s:string)返回strtok_t;
--strtok缓冲区中的标记化字符串
函数strtok_next(t:strtok_t)返回strtok_t;
--比较字符串
函数strcmpi(s1:string;s2:string)返回布尔值;
--将字符串转换为整数
函数str2integer(s:string)返回整数;
端包装;
包装体包装花式字符串为
函数is_空间(c:字符)返回布尔值is
开始
如果(c=''),那么
返回true;
如果结束;
如果(c str'length-1)那么
出口
如果结束;
端环;
S:=str;
结束程序;
--返回长度为n的字符串,如果最初小于n,则用nul填充
函数strpad(n:natural;x:string;rm\u注释:boolean)
返回字符串为
变量r:字符串(1到n);
可变停止:自然;
开始
对于1到n循环中的i
r(i):=字符值(0);
端环;
停止:=x'长度;
如果(停止>=n),则
停止:=n-1;
如果结束;
对于1中的i,停止循环
--忽略“#”之后的所有在线内容
如果(x(i)='#'),那么
出口
如果结束;
r(i):=x(i);
端环;
返回r;
末端功能;
--使用未解析的字符串初始化strtok结构
函数strtok_init(
s:字符串
)返回strtok\u t is
变量t:strtok_t;
变量一:自然变量;
变量ch:字符;
开始
t、 str:=strpad(STRTOK_MAX,s,true);
t、 位置:=1;
t、 更多:=正确;
t、 有效:=假--tok字符串尚未生效
t、 误差:=0;
返回t;
末端功能;
--strtok缓冲区中的标记化字符串
函数strtok_next(
t:strtok\u t
)返回strtok\u t is
变量ch:character:=character'val(0);
变量i:自然:=0;
变量r:strtok_t;
开始
r:=t;
--零t.tok
r、 len:=0;
对于1到r.tok'长度循环中的i
r、 tok(i):=字符'val(0);
端环;
--就餐空间
环
如果(r.pos>r.str'length-1),则
r、 有效:=假;
r、 更多:=假;
返回r;
如果结束;
ch:=r.str(r.pos);
如果(is_nul(ch)=真),则
r、 有效:=假;
r、 更多:=假;
返回r;
如果结束;
如果(is_space(ch)=false),则
出口
其他的
r、 位置:=r.pos+1;
如果结束;
端环;
--保存令牌
i:=1;
环
如果(i>r.tok'length-1),那么
r、 有效:=真;
r、 更多:=正确;
r、 误差:=1;
返回r;
如果结束;
如果((r.pos>r.str'length)或是num(r.str(r.pos)),那么
r、 有效:=(r.tok'length/=0);
r、 更多:=假;
r、 误差:=0;
返回r;
如果结束;
ch:=r.str(r.pos);
如果(是_空间(ch)),那么
r、 有效:=真;
r、 更多:=正确;
r、 误差:=0;
返回r;
其他的
r、 tok(i):=ch;
r、 len:=i;
i:=i+1;
r、 位置:=r.pos+1;
如果结束;
端环;
--我不应该到这里
r、 误差:=2;
r、 有效:=假;
r、 更多:=假;
返回r;
末端功能;
--字符串比较
函数strcmpi(s1:string;s2:string)
返回布尔值为
变量最大值:自然值:=0;
变量end_s1:布尔值;
变量end_s2:布尔型;
变量num_s1:布尔值;
变量nul_s2:布尔值;
开始
如果(s1'长度>=s2'长度),则最大值:=s1'长度;否则最大值:=s2'长度;如果结束;
对于1到最大循环中的i
端部s1:=(i>s1'长度);
结束_s2:=(i>s2'长度);
如果(end_s1和end_s2),则返回true;如果结束;
如果(结束s1),则
nul_s2:=(s2(i)=字符值(0));
如果为(nul_s2),则返回true;如果结束;
如果结束;
如果(结束)_s2
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;

package pkg_fancy_strings is

    -- Max Line length to tokenize
    constant STRTOK_MAX : natural := 200;

    procedure line2string(L: inout line; S: out string);

    function is_space (c:character) return boolean;
    function is_nul   (c:character) return boolean;

    -- structure to maintain state between strtok calls
    type strtok_t is
    record
        str   : string(1 to STRTOK_MAX);  --input string
        pos   : natural;                  --input string iterator position
        more  : boolean;                  --call strtok_next until more equals false stop 
        tok   : string(1 to STRTOK_MAX);  --token string value
        len   : natural;                  --token string length
        valid : boolean;                  --token string valid
        error : natural;                  --token string had an error, ex: truncation
    end record;

    -- return string of length n padded with nul if less than n originally
    function strpad(n: natural; x: string; rm_comment: boolean) return string;

    -- Initialize strtok structure with unparsed string
    function strtok_init(s : string) return strtok_t;

    -- tokenize string in strtok buffer
    function strtok_next(t: strtok_t) return strtok_t;

    -- compare strings  
    function strcmpi(s1: string; s2: string)  return boolean;   

    -- convert string into integer
    function str2integer(s: string) return integer;

end package;


package body pkg_fancy_strings is


    function is_space(c:character) return boolean is
    begin
        if (c = ' ') then
            return true;
        end if;

        if (c <= character'val(13)) then
           return true;
        end if;

        return false;        
    end function;

    function is_nul(c:character) return boolean is
    begin
        if (c = character'val(0)) then
            return true;
        end if;

        return false;        
    end function;

    procedure line2string(L: inout line; S: out string) is
        variable good  :boolean;
        variable ch    :character;
        variable str   :string(1 to STRTOK_MAX);
        variable i     :integer := 1;
        variable len   :integer := 0;
    begin

        -- Zero Line Buffer
        for i in 1 to str'length loop
            str(i) := character'val(0);
        end loop;

        len := 1;           
        loop 

            read(L, ch, good);
            if (good = false) then
                exit;
            end if;

            str(len) := ch;
            len      := len + 1;

            if (is_nul(ch)) then
               exit;
            end if;

            if (len > str'length-1) then
                exit;
            end if;

        end loop;

        S := str;

    end procedure;

    -- return string of length n padded with nul if less than n originally
    function strpad(n: natural; x: string; rm_comment: boolean) 
        return string is
        variable r:    string(1 to n);
        variable stop: natural;
    begin
        for i in 1 to n loop
            r(i) := character'val(0);
        end loop;

        stop := x'length;
        if (stop >= n) then
          stop := n-1;
        end if;

        for i in 1 to stop loop
            -- ignore everything on line after '#'
            if (x(i) = '#') then
               exit;
            end if;
            r(i) := x(i);
        end loop;

        return r;
    end function;



    -- Initialize strtok structure with unparsed string
    function strtok_init(
        s : string
    ) return strtok_t is
        variable t  :strtok_t;
        variable i  :natural;
        variable ch :character;
    begin

        t.str   := strpad(STRTOK_MAX, s, true);
        t.pos   := 1;
        t.more  := true;
        t.valid := false;  --tok string not valid yet
        t.error := 0;
        return t;

    end function;

    -- tokenize string in strtok buffer
    function strtok_next(
        t: strtok_t
    ) return strtok_t is
        variable ch   :character := character'val(0);
        variable i    :natural   := 0;
        variable r    :strtok_t;

    begin    
        r := t;

        -- Zero t.tok
        r.len := 0;
        for i in 1 to r.tok'length loop
            r.tok(i) := character'val(0);
        end loop;

        -- Eat Spaces
        loop
            if (r.pos > r.str'length-1) then
                r.valid    := false;
                r.more     := false;
                return r;
            end if;

            ch := r.str(r.pos);           

            if (is_nul(ch) = true) then
                r.valid    := false;
                r.more     := false;
                return r;
            end if;

            if (is_space(ch) = false) then
               exit;
            else 
               r.pos    := r.pos + 1;           
            end if;
        end loop; 

        -- Save Token
        i    := 1;
        loop
              if (i > r.tok'length-1) then
                r.valid    := true;
                r.more     := true;
                r.error    := 1;
                return r;
            end if;

            if ((r.pos > r.str'length) or is_nul(r.str(r.pos))) then
                r.valid    := (r.tok'length /= 0);
                r.more     := false;
                r.error    := 0;
                return r;
            end if;

            ch := r.str(r.pos);           
            if (is_space(ch)) then
                r.valid    := true;
                r.more     := true;
                r.error    := 0;
                return r;
            else 
               r.tok(i) := ch;
               r.len    := i;
               i        := i + 1;
               r.pos    := r.pos + 1;           
            end if;
        end loop; 

        -- shouldn't get here    
        r.error    := 2;
        r.valid    := false;
        r.more     := false;
        return r;   

    end function;

    --string compare
    function strcmpi(s1: string; s2: string)     
        return boolean is
        variable max: natural := 0;
        variable end_s1:boolean;
        variable end_s2:boolean;
        variable nul_s1:boolean;
        variable nul_s2:boolean;
    begin 
        if (s1'length >= s2'length) then  max := s1'length; else max := s2'length; end if;

        for i in 1 to max loop 
            end_s1 := (i > s1'length);
            end_s2 := (i > s2'length);

            if (end_s1 and end_s2) then return true; end if;

            if (end_s1) then
                nul_s2 := (s2(i) = character'val(0));
                if (nul_s2) then return true; end if;
            end if;

            if (end_s2) then
                nul_s1 := (s1(i) = character'val(0));
                if (nul_s1) then return true; end if;
            end if;

            nul_s1 := (s1(i) = character'val(0));
            nul_s2 := (s2(i) = character'val(0));

            if (nul_s1 and nul_s2) then return true; end if;

            if(s1(i) /= s2(i)) then 
              return false; 
            end if; 

        end loop; 

        return true;
    end function;

    -- read next whitespace delimited string
    --     return string is terminated with null's
    procedure read_string(L: inout Line; s: out string(1 to 80); 
                 good: out boolean) is
        variable c     :character;      
        variable r     :string(1 to 80);
        variable i     :natural;
    begin
        r := (others => character'val(0));
        s := (others => character'val(0));

        -- Skip WhiteSpace
        loop
            read(L, c, good);
            report "c:" & character'image(c);
            if (good = False) then
                good := False;
                return;
            elsif ((c = ' ') or (c <= character'val(13)) ) then
                next;
            end if;
            exit;
        end loop;

        -- Read Until Non-Whitespace
        i    := 1;
        r(i) := c;
        i    := i+1;
        loop
            read(L, c, good);
            if (good = false) then
                s    := r;
                good := True;               
                return;
            elsif ((c = ' ') or (c <= character'val(13)) ) then
                s := r;
                good := True;               
                return;
            else 
                r(i) := c;
                i    := i + 1;
            end if;
        end loop;

    end procedure;

end package body;

-- EXAMPLE OF FANCY STRINGS USAGE:
--
--    use work.pkg_fancy_strings.all;
--    
--    entity tb is
--    end entity;
--    
--    architecture rtl of tb is
--    begin
--        process
--          file      stim_in        :text open read_mode is "testcase1.txt";
--          variable  L              :line;
--          variable  sbuf           :string(1 to STRTOK_MAX);
--          variable  slen           :natural;
--          variable  t              :strtok_t;
--        begin
--            t := strtok_init("   mary had a little #lamb");
--            while(t.more) loop        
--                t := strtok_next(t);
--                if (t.valid) then
--                    report ">>" & t.tok(1 to t.len) & "<<";
--                end if;
--            end loop;
--        
--            report "done." severity failure;
--        end process;
--    end architecture;
--