运行 后重置输出
Reset output after run
我正在做一个学习 VHDL 的小项目。目前我正在研究 BCD 转换器(将二进制转换为其 BCD 数)。
但是我在实现测试台时卡住了。它不会在应用模式后重置输出。
我的实体VHDL代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bcd_mod is
port (
entry: in std_logic_vector(16 downto 0);
outp: out std_logic_vector(20 downto 0)
);
end bcd_mod;
architecture calculate of bcd_mod is
begin
process(entry)
variable outp_cp : std_logic_vector(20 downto 0) := (others => '0');
variable place : integer := 1;
variable digit : integer := 0;
variable number : integer := 0;
begin
for i in 16 downto 0 loop
case entry(i) is
when '0' => null;
when '1' => number := number + (2**i);
when others => null;
end case;
end loop;
if number > 99999 then
outp_cp(20) := '1';
else
while (number > 0) loop
digit := number mod 10;
if place = 1 then
outp_cp(3 downto 0) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 2 then
outp_cp(7 downto 4) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 3 then
outp_cp(11 downto 8) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 4 then
outp_cp(15 downto 12) := std_logic_vector(to_unsigned(digit, 4));
else
outp_cp(19 downto 16) := std_logic_vector(to_unsigned(digit, 4));
end if;
number := number - digit;
number := number / 10;
place := place + 1;
end loop;
end if;
outp <= outp_cp;
outp_cp := (others => '0');
end process;
end calculate;
我的代码测试平台:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bcd_mod_testbench is
end bcd_mod_testbench;
architecture calculate of bcd_mod_testbench is
component bmt
port(entry : in std_logic_vector(16 downto 0); outp : out std_logic_vector(20 downto 0));
end component;
for bmt_0: bmt use entity work.bcd_mod;
signal entry : std_logic_vector(16 downto 0);
signal outp : std_logic_vector(20 downto 0);
begin
bmt_0: bmt port map (entry => entry, outp => outp);
process
type pattern_type is record
entry : std_logic_vector(16 downto 0);
outp : std_logic_vector(20 downto 0);
end record;
type pattern_array is array (natural range <>) of pattern_type;
constant patterns : pattern_array :=
(("00000110111101101", "000000011010101100101"),
("00000000000000011", "000000000000000000011"),
("00000000000011011", "000000000000000100111"));
begin
for i in patterns'range loop
entry <= patterns(i).entry;
wait for 1 ns;
assert outp = patterns(i).outp
report "Wrong BCD number." severity error;
end loop;
assert false report "End of test." severity note;
wait;
end process;
end calculate;
这是 GTKWave 中的输出。你可以在这里看到,在 运行 带有大数字的代码之后,后面的数字从前面的数字结束的地方开始。
(可点击)
希望得到任何提示来解决这个问题。
在 VHDL 中,variable
在进程重新进入之间保留它的值。因此,当您输入数字 X"000003"
的过程时,您的所有变量仍然具有它们在 X"003565"
.
处理结束时添加的值
快速测试表明在进程开始时将 place
设置为 1
可以解决问题:
process(entry)
variable outp_cp : std_logic_vector(20 downto 0) := (others => '0');
variable place : integer := 1;
variable digit : integer := 0;
variable number : integer := 0;
begin
place := 1;
...
您的问题出在bcd_mod
中未标记的进程中。您没有在每个新条目上将 place
初始化为 1:
architecture calculate of bcd_mod is
begin
unlabeled:
process(entry)
variable outp_cp: std_logic_vector(20 downto 0) := (others => '0');
variable place: integer := 1;
variable digit: integer := 0;
variable number: integer := 0;
begin
place := 1; -- ADDED
for i in 16 downto 0 loop
如果您查看二进制值,问题就会变得很明显,这是我在您的测试台中使用报告语句所做的:
architecture foo of bcd_mod_testbench is
component bmt
port (
entry: in std_logic_vector(16 downto 0);
outp: out std_logic_vector(20 downto 0)
);
end component;
for bmt_0: bmt use entity work.bcd_mod;
signal entry: std_logic_vector(16 downto 0);
signal outp: std_logic_vector(20 downto 0);
function to_string(inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end;
begin
bmt_0:
bmt
port map (
entry => entry,
outp => outp
);
unlabeled:
process
type pattern_type is record
entry: std_logic_vector(16 downto 0);
outp: std_logic_vector(20 downto 0);
end record;
type pattern_array is array (natural range <>) of pattern_type;
constant patterns: pattern_array := (
("00000110111101101", "000000011010101100101"),
("00000000000000011", "000000000000000000011"),
("00000000000011011", "000000000000000100111")
);
begin
for i in patterns'range loop
entry <= patterns(i).entry;
wait for 1 ns;
assert outp = patterns(i).outp
report "Wrong BCD number pattern (" & integer'image(i) & ")"
severity error;
report "entry = " & to_string(entry);
report "outp = " & to_string(outp);
end loop;
assert false report "End of test." severity note;
wait;
end process;
end architecture;
给出:
bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:116:13:@2ns:(assertion error): Wrong BCD number pattern (1)
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000110000000000000000
bcd_mod_tb.vhdl:116:13:@3ns:(assertion error): Wrong BCD number pattern (2)
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000100000000000000000
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.
并且place初始化的时候没有报错:
bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000000000000000000011
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000000000000000100111
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.
添加了 to_string
功能以支持 '93 兼容的 VHDL 工具。
我正在做一个学习 VHDL 的小项目。目前我正在研究 BCD 转换器(将二进制转换为其 BCD 数)。
但是我在实现测试台时卡住了。它不会在应用模式后重置输出。
我的实体VHDL代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bcd_mod is
port (
entry: in std_logic_vector(16 downto 0);
outp: out std_logic_vector(20 downto 0)
);
end bcd_mod;
architecture calculate of bcd_mod is
begin
process(entry)
variable outp_cp : std_logic_vector(20 downto 0) := (others => '0');
variable place : integer := 1;
variable digit : integer := 0;
variable number : integer := 0;
begin
for i in 16 downto 0 loop
case entry(i) is
when '0' => null;
when '1' => number := number + (2**i);
when others => null;
end case;
end loop;
if number > 99999 then
outp_cp(20) := '1';
else
while (number > 0) loop
digit := number mod 10;
if place = 1 then
outp_cp(3 downto 0) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 2 then
outp_cp(7 downto 4) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 3 then
outp_cp(11 downto 8) := std_logic_vector(to_unsigned(digit, 4));
elsif place = 4 then
outp_cp(15 downto 12) := std_logic_vector(to_unsigned(digit, 4));
else
outp_cp(19 downto 16) := std_logic_vector(to_unsigned(digit, 4));
end if;
number := number - digit;
number := number / 10;
place := place + 1;
end loop;
end if;
outp <= outp_cp;
outp_cp := (others => '0');
end process;
end calculate;
我的代码测试平台:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bcd_mod_testbench is
end bcd_mod_testbench;
architecture calculate of bcd_mod_testbench is
component bmt
port(entry : in std_logic_vector(16 downto 0); outp : out std_logic_vector(20 downto 0));
end component;
for bmt_0: bmt use entity work.bcd_mod;
signal entry : std_logic_vector(16 downto 0);
signal outp : std_logic_vector(20 downto 0);
begin
bmt_0: bmt port map (entry => entry, outp => outp);
process
type pattern_type is record
entry : std_logic_vector(16 downto 0);
outp : std_logic_vector(20 downto 0);
end record;
type pattern_array is array (natural range <>) of pattern_type;
constant patterns : pattern_array :=
(("00000110111101101", "000000011010101100101"),
("00000000000000011", "000000000000000000011"),
("00000000000011011", "000000000000000100111"));
begin
for i in patterns'range loop
entry <= patterns(i).entry;
wait for 1 ns;
assert outp = patterns(i).outp
report "Wrong BCD number." severity error;
end loop;
assert false report "End of test." severity note;
wait;
end process;
end calculate;
这是 GTKWave 中的输出。你可以在这里看到,在 运行 带有大数字的代码之后,后面的数字从前面的数字结束的地方开始。
希望得到任何提示来解决这个问题。
在 VHDL 中,variable
在进程重新进入之间保留它的值。因此,当您输入数字 X"000003"
的过程时,您的所有变量仍然具有它们在 X"003565"
.
快速测试表明在进程开始时将 place
设置为 1
可以解决问题:
process(entry)
variable outp_cp : std_logic_vector(20 downto 0) := (others => '0');
variable place : integer := 1;
variable digit : integer := 0;
variable number : integer := 0;
begin
place := 1;
...
您的问题出在bcd_mod
中未标记的进程中。您没有在每个新条目上将 place
初始化为 1:
architecture calculate of bcd_mod is
begin
unlabeled:
process(entry)
variable outp_cp: std_logic_vector(20 downto 0) := (others => '0');
variable place: integer := 1;
variable digit: integer := 0;
variable number: integer := 0;
begin
place := 1; -- ADDED
for i in 16 downto 0 loop
如果您查看二进制值,问题就会变得很明显,这是我在您的测试台中使用报告语句所做的:
architecture foo of bcd_mod_testbench is
component bmt
port (
entry: in std_logic_vector(16 downto 0);
outp: out std_logic_vector(20 downto 0)
);
end component;
for bmt_0: bmt use entity work.bcd_mod;
signal entry: std_logic_vector(16 downto 0);
signal outp: std_logic_vector(20 downto 0);
function to_string(inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end;
begin
bmt_0:
bmt
port map (
entry => entry,
outp => outp
);
unlabeled:
process
type pattern_type is record
entry: std_logic_vector(16 downto 0);
outp: std_logic_vector(20 downto 0);
end record;
type pattern_array is array (natural range <>) of pattern_type;
constant patterns: pattern_array := (
("00000110111101101", "000000011010101100101"),
("00000000000000011", "000000000000000000011"),
("00000000000011011", "000000000000000100111")
);
begin
for i in patterns'range loop
entry <= patterns(i).entry;
wait for 1 ns;
assert outp = patterns(i).outp
report "Wrong BCD number pattern (" & integer'image(i) & ")"
severity error;
report "entry = " & to_string(entry);
report "outp = " & to_string(outp);
end loop;
assert false report "End of test." severity note;
wait;
end process;
end architecture;
给出:
bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:116:13:@2ns:(assertion error): Wrong BCD number pattern (1)
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000110000000000000000
bcd_mod_tb.vhdl:116:13:@3ns:(assertion error): Wrong BCD number pattern (2)
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000100000000000000000
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.
并且place初始化的时候没有报错:
bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000000000000000000011
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000000000000000100111
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.
添加了 to_string
功能以支持 '93 兼容的 VHDL 工具。