2014-06-20 43 views

回答

4

首先使该转换std_logicstd_logic_vectorstring喜欢的功能:

function to_bstring(sl : std_logic) return string is 
    variable sl_str_v : string(1 to 3); -- std_logic image with quotes around 
begin 
    sl_str_v := std_logic'image(sl); 
    return "" & sl_str_v(2); -- "" & character to get string 
end function; 

function to_bstring(slv : std_logic_vector) return string is 
    alias slv_norm : std_logic_vector(1 to slv'length) is slv; 
    variable sl_str_v : string(1 to 1); -- String of std_logic 
    variable res_v : string(1 to slv'length); 
begin 
    for idx in slv_norm'range loop 
    sl_str_v := to_bstring(slv_norm(idx)); 
    res_v(idx) := sl_str_v(1); 
    end loop; 
    return res_v; 
end function; 

使用逐位格式的优点是任何非01值将显示 与确切的std_logic值,这不是例如十六进制 演示文稿。

然后使过程从std_logicstd_logic_vector写入字符串文件,例如在像rising_edge(clk)

library std; 
use std.textio.all; 
... 
process (clk) is 
    variable line_v : line; 
    file  out_file : text open write_mode is "out.txt"; 
begin 
    if rising_edge(clk) then 
    write(line_v, to_bstring(rst) & " " & to_bstring(cnt_1) & " " & to_bstring(cnt_3)); 
    writeline(out_file, line_v); 
    end if; 
end process; 

上面的示例使用rststd_logic,和cnt_1cnt_3作为 std_logic_vector(7 downto 0)。在 “out.txt” 由此产生的输出是:

1 00000000 00000000 
1 00000000 00000000 
1 00000000 00000000 
0 00000000 00000000 
0 00000001 00000011 
0 00000010 00000110 
0 00000011 00001001 
0 00000100 00001100 
0 00000101 00001111 
0 00000110 00010010 
1

因为有对皮肤有猫不止一种方法:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
-- library std; 
use std.textio.all; 

entity changed_morten is 
end entity; 

architecture foo of changed_morten is 

    signal clk: std_logic := '0'; 
    signal rst: std_logic := '1'; 
    signal cnt_1: unsigned (7 downto 0); 
    signal cnt_3: unsigned (7 downto 0); 

    function string_it (arg:unsigned) return string is 
     variable ret: string (1 to arg'LENGTH); 
     variable str: string (1 to 3); -- enumerated type "'X'" 
     alias varg: unsigned (1 to arg'LENGTH) is arg; 
    begin 
     if arg'LENGTH = 0 then 
      ret := ""; 
     else 
      for i in varg'range loop 
       str := std_logic'IMAGE(varg(i)); 
       ret(i) := str(2); -- the actual character 
      end loop; 
     end if; 
     return ret; 
    end function; 

begin 


PRINT:   
    process (clk) is 
     variable line_v : line; 
     variable str: string (1 to 3); -- size matches charcter enumeration 
     file  out_file : text open write_mode is "out.txt"; 
    begin 
     if rising_edge(clk) then 
      str := std_logic'IMAGE(rst); 
      write (line_v, 
        str(2) & " " & 
        string_it(cnt_1) & " " & 
        string_it(cnt_3) & " " 
       ); 
      writeline(out_file, line_v); 
     end if; 
    end process; 

COUNTER1: 
    process (clk,rst) 
    begin 
     if rst = '1' then 
      cnt_1 <= (others => '0'); 
     elsif rising_edge(clk) then 
      cnt_1 <= cnt_1 + 1; 
     end if; 
    end process; 

COUNTER3: 
    process (clk,rst) 
    begin 
     if rst = '1' then 
      cnt_3 <= (others => '0'); 
     elsif rising_edge(clk) then 
      cnt_3 <= cnt_3 + 3; 
     end if; 
    end process; 

RESET: 
    process 
    begin 
     wait until rising_edge(clk); 
     wait until rising_edge(clk); 
     wait until rising_edge(clk); 
     rst <= '0'; 
     wait; 
    end process; 

CLOCK: 
    process 
    begin 
     wait for 10 ns; 
     clk <= not clk; 
     if Now > 210 ns then 
      wait; 
     end if; 
    end process; 

end architecture; 

而且大多是因为莫滕的表情

"" & std_logic'image(sl)(2); -- "" & character to get string 

ISN '不被ghdl接受,它不是索引名称,字符串是未命名的。

此问题似乎是由于未识别出被识别为索引名称前缀的函数调用('IMAGE)导致的。对于任何ghdl用户,您希望使用名为string target的中介作为属性函数调用的输出(显示在string_it函数中,并在PRINT过程中在行中)。我提交了一个错误报告。

附录

另一种方式来表达莫滕的to_bstring(SL:STD_LOGIC)返回字符串函数是:

function to_bstring(sl : std_logic) return string is 
    variable sl_str_v : string(1 to 3) := std_logic'image(sl); -- character literal length 3 
begin 
    return "" & sl_str_v(2); -- "" & character to get string 
end function; 

而这个工作的原因是因为函数调用动态阐述,意义每次调用函数时都会创建字符串sl_str_v。

参见IEEE标准1076-1993 12.5动态细化,b。:

子程序调用的执行包括详细说明相应的子程序声明的参数接口列表 ; 这涉及到每个接口声明的阐述,以创建相应的形式参数 。与形式参数相关的实际参数是 。最后,如果 子程序的指示符没有用 程序包STANDARD中定义的'FOREIGN属性修饰,则详细说明相应子程序 正文的声明部分,并执行子程序 正文中的语句顺序。

在IEEE Std 1076-2008,14.6中,对子程序调用动态阐述的描述有所扩展。

+0

感谢您的意见。我更新了我的答案以支持GHDL并使用迭代(在这种情况下不需要递归,有些人可能会觉得难以阅读)。 –

+0

@MortenZilmer你的回答没有错。至少在两台分析仪/模拟器中工作良好。只是在ghdl中没有那么多,我希望修正它,明显的解析器捷径或不完整的语义规则。应该在IEEE Std 1076-1987至-2008工作。 (我发誓我以前见过这个bug,在本地存档中找不到任何东西)。分析这些是我从stackoverflow中获得的。 – user1155120

+0

显然现在固定在ghdl主干上。目前还没有一个ghdl-0.32发布的日期,但是从最新的源代码构建ghdl,它应该可以工作。 –

0

我想提出一个灵活的方式来STD_LOGIC(_Vector)转换为字符串:

首先,你可以定义两个函数STD_LOGIC位和数字转换为字符:

FUNCTION to_char(value : STD_LOGIC) RETURN CHARACTER IS 
BEGIN 
    CASE value IS 
     WHEN 'U' =>  RETURN 'U'; 
     WHEN 'X' =>  RETURN 'X'; 
     WHEN '0' =>  RETURN '0'; 
     WHEN '1' =>  RETURN '1'; 
     WHEN 'Z' =>  RETURN 'Z'; 
     WHEN 'W' =>  RETURN 'W'; 
     WHEN 'L' =>  RETURN 'L'; 
     WHEN 'H' =>  RETURN 'H'; 
     WHEN '-' =>  RETURN '-'; 
     WHEN OTHERS => RETURN 'X'; 
    END CASE; 
END FUNCTION; 

function to_char(value : natural) return character is 
begin 
    if (value < 10) then 
     return character'val(character'pos('0') + value); 
    elsif (value < 16) then 
     return character'val(character'pos('A') + value - 10); 
    else 
     return 'X'; 
    end if; 
end function; 

现在它是可能的定义,从布尔和std_logic_vector转换成线二to_string功能:

function to_string(value : boolean) return string is 
begin 
    return str_to_upper(boolean'image(value)); -- ite(value, "TRUE", "FALSE"); 
end function; 

FUNCTION to_string(slv : STD_LOGIC_VECTOR; format : CHARACTER; length : NATURAL := 0; fill : CHARACTER := '0') RETURN STRING IS 
    CONSTANT int     : INTEGER    := ite((slv'length <= 31), to_integer(unsigned(resize(slv, 31))), 0); 
    CONSTANT str  : STRING := INTEGER'image(int); 
    CONSTANT bin_len : POSITIVE := slv'length; 
    CONSTANT dec_len : POSITIVE := str'length;--log10ceilnz(int); 
    CONSTANT hex_len : POSITIVE := ite(((bin_len MOD 4) = 0), (bin_len/4), (bin_len/4) + 1); 
    CONSTANT len  : NATURAL := ite((format = 'b'), bin_len, 
             ite((format = 'd'), dec_len, 
             ite((format = 'h'), hex_len, 0))); 

    VARIABLE j   : NATURAL := 0; 
    VARIABLE Result  : STRING(1 TO ite((length = 0), len, imax(len, length))) := (OTHERS => fill); 

BEGIN 
    IF (format = 'b') THEN 
     FOR i IN Result'reverse_range LOOP 
      Result(i) := to_char(slv(j)); 
      j   := j + 1; 
     END LOOP; 
    ELSIF (format = 'd') THEN 
     Result(Result'length - str'length + 1 TO Result'high) := str; 
    ELSIF (format = 'h') THEN 
     FOR i IN Result'reverse_range LOOP 
      Result(i) := to_char(to_integer(unsigned(slv((j * 4) + 3 DOWNTO (j * 4))))); 
      j   := j + 1; 
     END LOOP; 
    ELSE 
     REPORT "unknown format" SEVERITY FAILURE; 
    END IF; 

    RETURN Result; 
END FUNCTION; 

这to_string功能可以转换STD _logic_vectors为二进制(format ='b'),二进制(format ='d')和十六进制(format ='h')。可选地,如果长度大于0,则可以为字符串定义最小长度;如果std_logic_vector的所需长度短于长度,则可以定义填充字符。

这里是必需的辅助函数:

-- calculate the minimum of two inputs 
function imin(arg1 : integer; arg2 : integer) return integer is 
begin 
    if arg1 < arg2 then return arg1; end if; 
    return arg2; 
end function; 

-- if-then-else for strings 
FUNCTION ite(cond : BOOLEAN; value1 : STRING; value2 : STRING) RETURN STRING IS 
BEGIN 
    IF cond THEN 
     RETURN value1; 
    ELSE 
     RETURN value2; 
    END IF; 
END FUNCTION; 

-- a resize function for std_logic_vector 
function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is 
    constant high2b : natural := vec'low+length-1; 
    constant highcp : natural := imin(vec'high, high2b); 
    variable res_up : std_logic_vector(vec'low to high2b); 
    variable res_dn : std_logic_vector(high2b downto vec'low); 
begin 
    if vec'ascending then 
     res_up := (others => fill); 
     res_up(vec'low to highcp) := vec(vec'low to highcp); 
     return res_up; 
    else 
     res_dn := (others => fill); 
     res_dn(highcp downto vec'low) := vec(highcp downto vec'low); 
     return res_dn; 
end if; 
end function; 

Ok, this solution looks a bit long, but if you gather some of this functions -- and maybe overload them for several types -- you get an extended type converting system and in which you can convert nearly every type to every other type or representation. 
相关问题