2
votes

I am implementing a digital design in VHDL which has to be low power. The design has a lot of inputs that are declared as multiple standard logic vectors. The device is allowed to wake up if anything changes on any input. This has to be combinatorical logic because the device is in power down. The code of what I am trying to do says it all: (ToggleSTDBY is a signal so this is legal)

P_Wakeup: PROCESS (VEC1, VEC2, VEC3, Rst_N) IS
BEGIN
  IF Rst_N = '0' THEN
    ToggleSTDBY <= '0';
  ELSIF VEC1'event OR VEC2'event OR VEC3'event THEN
    ToggleSTDBY <= NOT(ToggleSTDBY);
  END IF;
END PROCESS P_Wakeup;    

This is legal in simulation, but upon synthesis it says "'event is only supported for single bit signals". How can I fix this? There are a total of 66 bits in the vectors all together and I really don't want to write 66 processes for waking the device up. A bitwise OR on all bits will not solve anything, since most signals will be high, so the OR on all bits will always result in a high. The following code:

P_Wakeup: PROCESS (VEC, Rst_N) IS
BEGIN
IF Rst_N = '0' THEN
  ToggleSTDBY <= '0';
ELSE
  FOR i IN VEC'RANGE LOOP
    IF VEC(i)'EVENT THEN
      ToggleSTDBY <= NOT(ToggleSTDBY);
    END IF;   
  END LOOP;
END IF;
END PROCESS P_Wakeup;

gives error "The prefix of signal attribute 'EVENT must be a static signal name". How can I fix it AND keep the code readable?

2
Is this possible to do without a clock? I would think that 'event needs to have some information about the previous state of the signal, which I would think would require a clock. Unless this can be done using latches? - Russell
@Russell: It's done with XOR and a delay line. The synthesis tool knows about the timing of the different blocks in the device, so it can ensure that the delay to each input of the XOR is different, so the XOR will pulse high although its inputs are the same signal, because transients reach one side before the other. There are also edge-detection circuits built into the clock inputs of DFF blocks. - Ben Voigt

2 Answers

2
votes

The HDL part of VHDL is abbreviation for Hardware Description Language (HDL), so the VHDL constructions you can use must be possible to map by the synthesis tool to the target. The use of 'event is typically tied to sequential (clocked) hardware elements like flip flops or RAMs, and the synthesis tool typically requires that you write the VHDL in a specific way, so the tool can identify that a particular hardware elements is to be used.

Even though you may write VHDL code for a simulator, for example ModelSim, that can compile and simulate use of 'event as in your examples, the synthesis tool will typically not be able to map this to any available target hardware element, since there is probably no such hardware elements as an 'event detector.

But an 'event actually indicates a change in signal value, so you can maybe write the signal value change detector explicitly in VHDL like:

change <= '1' if (vec_now /= vec_previous) else '0';

Depending on the low-power hardware elements available, you may start the clock when an '1' is detected asynchronously on change, maybe through ToggleSTDBY, and then process the change. The last thing before going into sleep mode is then to capture the current vec value in vec_previous, so another change can be detected while in sleep mode.

The possibility for doing low-power design of the kind I assume you are doing based on the description, depends entirely on the features provided in the target FPGA/ASIC technology. So before trying to get the VHDL syntax right, you may want to determine how the resulting hardware should look like, based on the available low power features.

1
votes

Even if it is possible to write a VHDL code that models your intended behavior, I believe it won't work as you expect. I suggest that before writing the code you try to sort out the details of how exactly your ToggleSTDBY would be set, tested, and reset (a circuit diagram could help).

If you decide to implement ToggleSTDBY as a vector, one solution for the "event is only supported for single bit signals" problem is to move the loop to outside the process, using a for-generate:

gen: for i in ToggleSTDBY'range generate

    p_wakeup : process (vec, rst_n) is
    begin
        if rst_n = '0' then
            ToggleSTDBY(i) <= '0';
        else
            if vec(i)'event then
                ToggleSTDBY(i) <= not (ToggleSTDBY(i));
            end if;
        end if;
    end process p_wakeup;

end generate;