如何在 vhdl 中将整数转换为带前导零的字符串?
How to convert integer to string with leading zeros in vhdl?
如何在 VHDL 中打印带前导零的整数?
本质上实现与 C 或 Python:
相同
printf("%05d", number);
str(number).zfill(5)
当然,这将仅用于模拟(写入文件或报告等)。
到目前为止,我想到的最好的方法是这个函数:
-- Range is limited to from 1 to 9 as 10 digit
-- integer can already overflow in VHDL
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d);
begin
if(a >= 10**d) then
return integer'image(a);
else
for i in 0 to d-1 loop
vString(d-i to d-i) := integer'image(a/(10**i) mod 10);
end loop;
return vString;
end if;
end function;
例如:
process is
variable number : integer := 42;
begin
report fIntToStringLeading0(number, 5);
wait;
end process;
输出:
# ** Note: 00042
这里有一条双线:
ZEROES := (others => '0');
ZEROES(ZEROES'length-integer'image(N)'length+1 to ZEROES'length) := integer'image(N);
例如
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
begin
process
constant MAXLENGTH : integer := 10;
variable N : integer;
variable ZEROES : string(1 to MAXLENGTH);
begin
N := 1234;
ZEROES := (others => '0');
ZEROES(ZEROES'length-integer'image(N)'length+1 to ZEROES'length) := integer'image(N);
report ZEROES;
wait;
end process;
end architecture LEADING_ZEROES;
https://www.edaplayground.com/x/4B84
最好将它包装在像您这样的函数中并添加您的检查:
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d) := (others => '0');
begin
if(a >= 10**d) then
return integer'image(a);
else
return vString(1 to vString'length-integer'image(a)'length) & integer'image(a);
end if;
end function;
例如
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d) := (others => '0');
begin
if(a >= 10**d) then
return integer'image(a);
else
return vString(1 to vString'length-integer'image(a)'length) & integer'image(a);
end if;
end function;
begin
process
begin
report fIntToStringLeading0(1234,5);
report fIntToStringLeading0(12345,6);
report fIntToStringLeading0(12345,3);
wait;
end process;
end architecture LEADING_ZEROES;
这是另一个想法,它通过使用 TEXTIO 写入过程来取消检查以确保需要任何前导零,该过程会进行此类检查。问题是,写入程序在前导空格中放置的不是零,并且用零代替空格很笨拙:
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable L : line;
begin
write(L,a,right,d);
for I in 1 to L.all'length loop
if L.all(I) = ' ' then
L.all(I) := '0';
end if;
end loop;
return L.all;
end function;
例如
use std.textio.all;
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable L : line;
begin
write(L,a,right,d);
for I in 1 to L.all'length loop
if L.all(I) = ' ' then
L.all(I) := '0';
end if;
end loop;
return L.all;
end function;
begin
process
begin
report fIntToStringLeading0(1234,5);
report fIntToStringLeading0(12345,6);
report fIntToStringLeading0(12345,3);
wait;
end process;
end architecture LEADING_ZEROES;
有一个针对 C 风格格式化的开源包。你会在这里找到它 https://github.com/suoto/hdl_string_format
有 VHDL 方式。编写一个通用的 to_dstring 函数:
use std.textio.all;
entity rightjustd is
end entity;
architecture foo of rightjustd is
type filltype is (NOFILL, ZEROFILL);
function to_dstring (
value: in integer;
field: in width := 0;
just: in side := RIGHT;
fill: in filltype := NOFILL
) return string is
variable retstr: string (1 to field);
begin
if field = 0 then
return integer'image(value);
elsif field < integer'image(value)'length then
retstr := (others => '#');
elsif fill = NOFILL or just = LEFT then
retstr := justify (integer'image(value), just, field);
else -- fill = ZEROFILL and just = RIGHT, field >= image length
retstr := justify (integer'image(abs value), just, field);
for i in retstr'range loop
if retstr(i) = ' ' then
retstr(i) := '0';
end if;
end loop;
if value < 0 then
retstr(1) := '-';
end if;
end if;
return retstr;
end function to_dstring;
begin
process
begin
report to_dstring(-2456, 12, RIGHT, ZEROFILL);
report to_dstring(-2456, 4, RIGHT, ZEROFILL);
report to_dstring(-2456);
report to_dstring(-2456, 12, LEFT, ZEROFILL) & '.';
report to_dstring(-2456, 12, RIGHT);
wait;
end process;
end architecture;
这还没有经过彻底的测试。测试用例产生:
rightjustd.vhdl:38:9:@0ms:(report note): -00000002456
rightjustd.vhdl:39:9:@0ms:(report note): ####
rightjustd.vhdl:40:9:@0ms:(report note): -2456
rightjustd.vhdl:41:9:@0ms:(report note): -2456 .
rightjustd.vhdl:42:9:@0ms:(report note): -2456
(class 常量)输入的初始值意味着您可以从右到左离开参数,一直到只提供一个整数值。
justify 函数调用需要 -2008 并在包 textio 中声明。
如果我没理解错的话,你只是想
printf("%05d", number); // in C
进入
print("%05d" % number) # in python
如何在 VHDL 中打印带前导零的整数?
本质上实现与 C 或 Python:
相同printf("%05d", number);
str(number).zfill(5)
当然,这将仅用于模拟(写入文件或报告等)。
到目前为止,我想到的最好的方法是这个函数:
-- Range is limited to from 1 to 9 as 10 digit
-- integer can already overflow in VHDL
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d);
begin
if(a >= 10**d) then
return integer'image(a);
else
for i in 0 to d-1 loop
vString(d-i to d-i) := integer'image(a/(10**i) mod 10);
end loop;
return vString;
end if;
end function;
例如:
process is
variable number : integer := 42;
begin
report fIntToStringLeading0(number, 5);
wait;
end process;
输出:
# ** Note: 00042
这里有一条双线:
ZEROES := (others => '0');
ZEROES(ZEROES'length-integer'image(N)'length+1 to ZEROES'length) := integer'image(N);
例如
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
begin
process
constant MAXLENGTH : integer := 10;
variable N : integer;
variable ZEROES : string(1 to MAXLENGTH);
begin
N := 1234;
ZEROES := (others => '0');
ZEROES(ZEROES'length-integer'image(N)'length+1 to ZEROES'length) := integer'image(N);
report ZEROES;
wait;
end process;
end architecture LEADING_ZEROES;
https://www.edaplayground.com/x/4B84
最好将它包装在像您这样的函数中并添加您的检查:
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d) := (others => '0');
begin
if(a >= 10**d) then
return integer'image(a);
else
return vString(1 to vString'length-integer'image(a)'length) & integer'image(a);
end if;
end function;
例如
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable vString : string(1 to d) := (others => '0');
begin
if(a >= 10**d) then
return integer'image(a);
else
return vString(1 to vString'length-integer'image(a)'length) & integer'image(a);
end if;
end function;
begin
process
begin
report fIntToStringLeading0(1234,5);
report fIntToStringLeading0(12345,6);
report fIntToStringLeading0(12345,3);
wait;
end process;
end architecture LEADING_ZEROES;
这是另一个想法,它通过使用 TEXTIO 写入过程来取消检查以确保需要任何前导零,该过程会进行此类检查。问题是,写入程序在前导空格中放置的不是零,并且用零代替空格很笨拙:
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable L : line;
begin
write(L,a,right,d);
for I in 1 to L.all'length loop
if L.all(I) = ' ' then
L.all(I) := '0';
end if;
end loop;
return L.all;
end function;
例如
use std.textio.all;
entity LEADING_ZEROES is
end entity ;
architecture LEADING_ZEROES of LEADING_ZEROES is
function fIntToStringLeading0 (a : natural; d : integer range 1 to 9) return string is
variable L : line;
begin
write(L,a,right,d);
for I in 1 to L.all'length loop
if L.all(I) = ' ' then
L.all(I) := '0';
end if;
end loop;
return L.all;
end function;
begin
process
begin
report fIntToStringLeading0(1234,5);
report fIntToStringLeading0(12345,6);
report fIntToStringLeading0(12345,3);
wait;
end process;
end architecture LEADING_ZEROES;
有一个针对 C 风格格式化的开源包。你会在这里找到它 https://github.com/suoto/hdl_string_format
有 VHDL 方式。编写一个通用的 to_dstring 函数:
use std.textio.all;
entity rightjustd is
end entity;
architecture foo of rightjustd is
type filltype is (NOFILL, ZEROFILL);
function to_dstring (
value: in integer;
field: in width := 0;
just: in side := RIGHT;
fill: in filltype := NOFILL
) return string is
variable retstr: string (1 to field);
begin
if field = 0 then
return integer'image(value);
elsif field < integer'image(value)'length then
retstr := (others => '#');
elsif fill = NOFILL or just = LEFT then
retstr := justify (integer'image(value), just, field);
else -- fill = ZEROFILL and just = RIGHT, field >= image length
retstr := justify (integer'image(abs value), just, field);
for i in retstr'range loop
if retstr(i) = ' ' then
retstr(i) := '0';
end if;
end loop;
if value < 0 then
retstr(1) := '-';
end if;
end if;
return retstr;
end function to_dstring;
begin
process
begin
report to_dstring(-2456, 12, RIGHT, ZEROFILL);
report to_dstring(-2456, 4, RIGHT, ZEROFILL);
report to_dstring(-2456);
report to_dstring(-2456, 12, LEFT, ZEROFILL) & '.';
report to_dstring(-2456, 12, RIGHT);
wait;
end process;
end architecture;
这还没有经过彻底的测试。测试用例产生:
rightjustd.vhdl:38:9:@0ms:(report note): -00000002456
rightjustd.vhdl:39:9:@0ms:(report note): ####
rightjustd.vhdl:40:9:@0ms:(report note): -2456
rightjustd.vhdl:41:9:@0ms:(report note): -2456 .
rightjustd.vhdl:42:9:@0ms:(report note): -2456
(class 常量)输入的初始值意味着您可以从右到左离开参数,一直到只提供一个整数值。
justify 函数调用需要 -2008 并在包 textio 中声明。
如果我没理解错的话,你只是想
printf("%05d", number); // in C
进入
print("%05d" % number) # in python