Reset output after startup

I am working on a small project to learn VHDL. I am currently working on a BCD converter (converting a binary code to its BCD number).

But I am stuck implementing testbench. It does not reset the output after templates have been applied.

My object VHDL code:

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;

      

My testbench for code:

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;

      

And here is the output in GTKWave. You can see here that after running the code with a large number, the next numbers start where the number ends.

GTKWave exit from testbench (Interactive)

Hope to get some tips on how to fix this problem.

+3


source to share


2 answers


In VHDL, a variable

retains the value between re-entering the process. This way, when you enter a process for a number X"000003"

, all your variables still have the value they add at the end of the processing X"003565"

.

A quick test shows that the installation is place

in 1

eliminating the problem at the beginning of the process:



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;

    ...

      

+2


source


Your problem is an unlabeled process in bcd_mod

. You don't initialize place

to 1 for every new entry:

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

      

And the problem becomes obvious if you look at the binary values ​​I made with the reports in your test jar:

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;

      

What gives:



bcd_mod_tb.vhdl: 119: 13: @ 1ns: (Memorandum): write = 00000110111101101
bcd_mod_tb.vhdl: 120: 13: @ 1ns: (note to report): outp = 000000011010101100101
bcd_modl_tb: 13: 13: 13 (assertion error): invalid BCD number pattern (1)
bcd_mod_tb.vhdl: 119: 13: @ 2ns: (note on report): entry = 00000000000000011
bcd_mod_tb.vhdl: 120: 13: @ 2ns: (note on report): outp = 000110000000000000000
bcd_mod_tb.vhdl: 116: 13: @ 3ns: (assertion error): invalid BCD number pattern (2)
bcd_mod_tb.vhdl: 119: 13: @ 3ns: (note on the report): 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.

And when the place is initialized, there is no error:

bcd_mod_tb.vhdl: 119: 13: @ 1ns: (Memorandum): write = 00000110111101101
bcd_mod_tb.vhdl: 120: 13: @ 1ns: (note to report): outp = 000000011010101100101
bcd_modl_tb: 13: 13 (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 .vhdl: 120: 13: @ 3ns: (note to report): outp = 000000000000000100111
bcd_mod_tb.vhdl: 122: 9: @ 3ns: (note to assertion): end of test.

Added a function to_string

to support 93 compatible VHDL tool.

+2


source







All Articles