Search code examples
for-loopvhdl

Assign multiple values to a signal during 1 process


If you assign a value to a signal in a process, does it only become the correct value of the signal at the end of the process? So there would be no point in assigning a value to a signal more than once per process, because the last assignment would be the only one that would be implemented, correct?

I'm a bit desperate because I'm trying to implement the booth algorithm in VHDL with signals and I can't get it baked. It wasn't a problem with variables, but signals make it all more difficult.

I tried a for loop, but that doesn't work because I have to update the values within the loop.

My next idea is a counter in the testbench.

Would be very thanksful for an idea!

my current Code look like this:

architecture behave of booth is
signal buffer_result1, buffer_result2, buffer_result3: std_logic_vector(7 downto 0) := "0000"&b;
signal s: std_logic:= '0';
signal count1, count2: integer:=0;

begin

    
    assignment: process(counter) is
    begin
        if counter = "000" then
            buffer_result1 <= "0000"&b;
        end if;
    end process;
    
    
    add_sub: process(counter) is
    begin
        if counter <= "011" then
            if(buffer_result1(0) = '1' and s = '0') then
                buffer_result2 <= buffer_result1(7 downto 4)-a;
            else if (buffer_result1(0) = '0' and s = '1') then
                buffer_result2 <= buffer_result1(7 downto 4)+a;
            end if;
        end if;
    end process;
    
    shift:process(counter) is
    begin
        if counter <= "011"
            buffer_result3(7) <= buffer_result2(7);
            buffer_result3(6 downto 0) <= buffer_result2(7 downto 1);
            s<= buffer_result3(0);
        else
            result<=buffer_result3;
        end if;
end behave;

Solution

  • Short answer: that's correct. A signal's value will not update until the end of your process.

    Long answer: A signal will only update when its assignment takes effect. Some signal assignments will use after and specify a time, making the transaction time explicit. Without an explicit time given, signals will update after the default "time-delta," an "instant" of simulation time that passes as soon as all concurrently executing statements at the given sim time have completed (e.g. a process). So your signals will hold their initial values until the process completes, at which point sim time moves forward one "delta," and the values update.

    That does not mean that multiple signal assignment statements to the same signal don't accomplish anything in a process. VHDL will take note of all assignments, but of a series of assignments given with the same transaction time, only the last assignment will take effect. This can be used for a few tricky things, although I've encountered differences of opinion on how often they should be tried. For instance:

    -- Assume I have a 'clk' coming in
    
    signal pulse   : std_ulogic;
    signal counter : unsigned(2 downto 0);
    
    pulse_on_wrap : process(clk) is
    begin
        clock : if rising_edge(clk):
            pulse   <= '0'; -- Default assignment to "pulse" is 0
            counter <= counter + 1; -- Counter will increment each clock cycle
            if counter = 2**3-1 then
                pulse <= '1'; -- Pulse high when the counter drops to 0 (after this cycle)
            end if;
        end if clock;
    end process pulse_on_wrap;
    

    Here, the typical behavior is to assign the value '0' to pulse on each clock cycle. But if counter hits its max value, there will be a following assignment to pulse, which will set it to '1' once simulation time advances. Because it comes after the '0' assignment and also has a "delta" transaction delay, it will override the earlier assignment. So this process will cause the signal pulse, fittingly, to go high for one cycle each time the counter wraps to zero and then drop the next - it's a pulse, after all! :^)

    I provide that example only to illustrate the potential benefit of multiple assignments within a process, as you mention that in your question. I do not advise trying anything fancy with assignments until you're clear on the difference between variable assignment and signal assignment - and how that needs to be reflected in your code!

    Try to think of things in terms of simulation time and hardware when it comes to signals. Everything is static until time moves forward, then you can handle the new values. It's a learning curve, but it'll happen! ;^)