Search code examples
vhdl

How do I add the bits of a vector and at the same time save the value in a vector signal? I use google translator**


I am trying to know if the amount of "1" in a std_logic_vector is an odd or even number. For that I am trying to use an "if" statement along with a counter, but I don't get the expected result.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity prueba2 is
port (
          entrada: in std_logic_vector(0 to 10)
        );
end prueba2;

architecture Behavioral of prueba2 is

signal bit1: std_logic_vector(0 to 3):= (others => '0');

begin

prueba: process(entrada)

    --variable suma: unsigned(0 to 2):= (others => '0');

begin
    for i in 0 to 10 loop
        if (entrada(i)= '1') then
            bit1 <= bit1+1;
        end if;
    end loop;

end process;

end Behavioral;


I am not getting errors in the syntax, but for example, by entering a vector "1111111111" I receive as output in the simulation, using ISE design Suite, the value "0001" instead of "1010". I appreciate your corrections and code suggestions.


Solution

  • See IEEE Std 1076-2008 10.5.2.2 Executing a simple assignment statement, 14.7.3.4 Simulation cycle and 14.7.3.4 Signal update.

    Signals aren't updated immediately. The current simulation cycle isn't complete until every process sensitive to an event has executed and potentially scheduled signal updates and subsequently suspended. Simulation time is advanced to the time the next signal update is scheduled. Signals are updated at the beginning of a simulation cycle before any suspended processes resume due to a signal event.

    Processes both suspend and resume executing wait statements (see 10.2 Wait statement). A process statement (11.3) with a sensitivity list has an implicit wait statement as the last statement with it's sensitivity list having the contents of the process sensitivity list.

    The signal bit1 won't update while the loop is executing, there is no implicit or explicit wait statement causing the process to suspend.

    To solve the issue use a variable:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use ieee.std_logic_unsigned.all;  -- arithmetic for std_logic_vector
    
    entity prueba2 is
        port (
            entrada: in std_logic_vector(0 to 10) := (others => '1')
        );
    end entity prueba2;
    
    architecture behavioral of prueba2 is
        signal bit1: std_logic_vector(0 to 3):= (others => '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 function;
    begin
    
    prueba: 
        process (entrada)  -- sensitivity list implies wait as final statement
            -- variable suma: unsigned(0 to 2):= (others => '0');
            variable suma: std_logic_vector(0 to 3); 
        begin
            suma := (others => '0'); -- start at 0 every time
            for i in entrada'range loop
                if entrada(i) = '1' then
                    -- bit1 <= bit1+1 -- signals don't update until the beginning
                    -- of the next simulation cycle (at the soonest)
                    suma := suma + 1; -- variables assignment is immediate
                end if;
            end loop;
            report "bit1 will be assigned " & to_string(suma); 
            bit1 <= suma; -- both the same length processes communicate with signals
            -- wait on entrada;  -- implicit wait statement, process suspends
        end process;
    end architecture behavioral;
    

    You can see the variable has the same length as bit1. That's required, you input entrada has a length of 11 which requires a 4 bit value to accumulate the number of '1's.

    There are some embellishments for testing. Some simulators will allow you to simulate a top level with ports as long as inputs have default values or can be forced. Here entrada is supplied with all '1's. The to_string function is provided in revision -2008 of the standard, also provided here for compatibility with earlier revisions. The report statement tells us the value of suma that will be assigned to bit1.

    When the design unit is analyzed and elaborated (compiled) then run:

    ghdl -a --ieee=synopsys -fexplicit prueba2.vhdl
    ghdl -e --ieee=synopsys -fexplicit prueba2
    ghdl -r prueba2
    prueba2.vhdl:37:9:@0ms:(report note): bit1 will be assigned 1011
    

    The loop has successfully counted all the '1's, and bit1 will have an update scheduled with the same simulation time (here 0 ms). The simulator will execute a follow on simulation cycle (a delta cycle) then without any further schedule signal updates scheduled in any projected output waveform (a queue) the simulation time will advance to TIME'HIGH and simulation will end.

    When a simulation starts every process executes at least once following initialization. The event on bit1 will cause a signal value update but there are no processes in the stand alone example sensitive to bit1 and simulation will cease.

    The default value on the input entrada, function to_string and the report statement can be removed, they are present for testing, a testbench not having been provided.