Search code examples
vhdl

VHDL adding 2 std_ulogic_vector does not have any effect


I am starting with VHDL and have some troubles.

I tried to implement the double dabble algorithm to convert an input binarystring to bcd code.

For this I have implemented it like in the wiki or in other references. However, I have the problem that

bcdVec(3 downto 0) <= std_ulogic_vector(unsigned(bcdVec(3 downto 0)) + unsigned(three));

does not have any effect (three = std_ulogic_vector(3 downto 0) := "0011"). I have tested it with a report statement before and after the calculation but it gives the same result.

at 210 ns(1): Note: 7 (/bcd_conversion_tb/uut/).
at 210 ns(1): Note: 7 (/bcd_conversion_tb/uut/).

Maybe someone has a nice hint for me, thanks!

If it helps here is the whole code of the process:

BCDProc: process(Reset, CLK_50M) is
begin
    if(Reset = ResetLevel) then
        working <= '0';
        i <= 0;
        ready <= '1';
        busy <= '0';
        bcdVec <= (others => '0');
        binVec <= binaryvec;
        hundrets_BCD <= (others => '0');
        tens_BCD <= (others => '0');
        ones_BCD <= (others => '0');
    elsif (CLK_50M'event AND CLK_50M = '1') then
        if(start = '1') then
            working <= '1';
            ready <= '0';
        end if;
        if(i = 7) then
            -- split vector to matching BCD values
            ones_BCD <= std_ulogic_vector(bcdVec(3 downto 0));
            tens_BCD <= std_ulogic_vector(bcdVec(7 downto 4));
            hundrets_BCD <= std_ulogic_vector(bcdVec(11 downto 8));
            i <= 0;
            tmp <= 0;
            ready <= '1';
            busy <= '0';
            working <= '0';
        end if;

        if (i < 8 AND working = '1') then
            busy <= '1';
            --check if bcd value is >4, if so then add 3
            if(i < 8 AND bcdVec (3 downto 0) > "0100") then
                report tmp'image(to_integer(unsigned(bcdVec(3 downto 0))));
                bcdVec(3 downto 0) <= std_ulogic_vector(unsigned(bcdVec(3 downto 0)) + unsigned(three));
                report tmp'image(to_integer(unsigned(bcdVec(3 downto 0))));
            end if;

            if(i < 8 AND bcdVec (7 downto 4) > "0100") then
                tmp <= to_integer(unsigned(bcdVec(7 downto 4)));
                tmp <= tmp + 3;
                bcdVec(7 downto 4) <= std_ulogic_vector(to_unsigned(tmp, 4));
            end if;

            if(i < 8 AND bcdVec (11 downto 8) > "0100") then
                tmp <= to_integer(unsigned(bcdVec(11 downto 8)));
                tmp <= tmp + 3;
                bcdVec(11 downto 8) <= std_ulogic_vector(to_unsigned(tmp, 4));
            end if;

            --perform the shiftoperations
            bcdVec(11 downto 0) <= bcdVec (10 downto 0) & binVec(7);
            binVec(7 downto 0) <= binVec(6 downto 0) & '0';

            --increment countervariable 
            i <= i+1;
        end if;
    end if;
end process BCDProc;

Solution

  • Signal assignments never update until a process suspends. This process only suspends at its sensitivity list. Hence your following snapshot of tmp will not add 3 to bcdVec, but instead will add 3 to the value tmp was on the last execution of the process - ie: the previous rising edge of CLK_50M.

        if(i < 8 AND bcdVec (11 downto 8) > "0100") then
            tmp <= to_integer(unsigned(bcdVec(11 downto 8)));
            tmp <= tmp + 3;
            bcdVec(11 downto 8) <= std_ulogic_vector(to_unsigned(tmp, 4));
        end if;
    

    You do similar things throughout your entire process. For example, you schedule working to go to '1' if start is '1', then later you override that value if "i = 7",

    if(start = '1') then
        working <= '1';
        ready <= '0';
    end if;
    
    if(i = 7) then
        . . .
        working <= '0';
    end if;
    

    and then later you try to test to see what is (excerpt below), however, the process has not suspended, so the the value of working has not been updated yet and it will still have the value it had on the previous execution.

    if (i < 8 AND working = '1') then