我需要得到幾個信號的值來檢查它們是否與仿真(仿真是在Matlab中)。有很多值,我想讓它們在一個文件中,以便我可以在腳本中運行它,並避免手動複製值。有沒有辦法將一個信號的值從一個modelsim模擬打印到一個文件中?
有沒有辦法將幾個信號的值自動打印到文本文件中?
(設計是VHDL實現)
我需要得到幾個信號的值來檢查它們是否與仿真(仿真是在Matlab中)。有很多值,我想讓它們在一個文件中,以便我可以在腳本中運行它,並避免手動複製值。有沒有辦法將一個信號的值從一個modelsim模擬打印到一個文件中?
有沒有辦法將幾個信號的值自動打印到文本文件中?
(設計是VHDL實現)
首先使該轉換std_logic
和std_logic_vector
到 string
喜歡的功能:
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_logic
和 std_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;
上面的示例使用rst
如std_logic
,和cnt_1
和cnt_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
因爲有對皮膚有貓不止一種方法:
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中,對子程序調用動態闡述的描述有所擴展。
我想提出一個靈活的方式來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.
感謝您的意見。我更新了我的答案以支持GHDL並使用迭代(在這種情況下不需要遞歸,有些人可能會覺得難以閱讀)。 –
@MortenZilmer你的回答沒有錯。至少在兩臺分析儀/模擬器中工作良好。只是在ghdl中沒有那麼多,我希望修正它,明顯的解析器捷徑或不完整的語義規則。應該在IEEE Std 1076-1987至-2008工作。 (我發誓我以前見過這個bug,在本地存檔中找不到任何東西)。分析這些是我從stackoverflow中獲得的。 – user1155120
顯然現在固定在ghdl主幹上。目前還沒有一個ghdl-0.32發佈的日期,但是從最新的源代碼構建ghdl,它應該可以工作。 –