Implementing Delay In a Case Statement
Maxplus 2 and VHDL itself don't support the implementation of delays inside a case statement. For example the following code:
case instruction is
when first_command =>
instruction1;
wait for 20 ns;
instruction2;
when second_command=>
instruction1;
.
.
.
will not be accepted, since Maxplus2 does not support the use of a delay command such as wait inside a conditional clause. However, when we are dealing with hardware that require a sequence of different signals to be sent out to it, with delays between each of them, this feature is needed, especially when there is more than one sequence to be sent. In this case, a case statement with delays in between instructions is needed.
This can be worked around using a counter attached to the entity containing the implementation of the case statement. A counter with an enable signal can be used to time the delay between instructions. The counter is enabled when the first instruction is run, and then the counter is done, it sets the enable signal for the next instruction.
The code for the counter follows:
entity DelayTimer is
port(
clock: in std_logic;
reset: in std_logic;
overflow: out std_logic; -- the signal that’s set when count is done
count_enable: in std_logic – signal to enable the counter);
end DelayTimer;
architecture behavior of DelayTimer is
signal counter_value: std_logic_vector(DELAY_COUNTER_WIDTH-1 downto 0);
begin
sync: process(clock) is
begin
if rising_edge(clock) then
if reset = '1' then
counter_value <= 0;
overflow <= '0';
elsif count_enable = '1' then
if (counter_value = VALUE_TO_COUNT) then
counter_value <= 0;
overflow <= '1';
else
counter_value <= counter_value + '1';
overflow <= '0';
end if;
else
counter_value <= counter_value;
overflow <= '0';
end if; -- reset | count | else
end if; -- rising clock edge
end process sync;
end behavior;
receive: process(clock)
begin
if rising_edge(clock) then
-- all actions are synchronous, and so they need the clock edge
if delay_done = '1' then
enable_delay <= '0'; -- stop counter and reset it
reset_delaytimer <= '1';
else
reset_delaytimer <= ‘0’;
end if;
case instruction is
when first_command =>
instruction1;
enable_delay <= ’1’; -- start counter
when second_command=>
instruction1;
.
.
.
Now there is a delay after the instruction inside the case statement, and the instruction’s value will remain this way until the delay time is up. The length of delay can be set by changing the DELAY_COUNTER_WIDTH constant inside the counter.
For additional information, contact Chen-song.
Group members:
Chen-song Qin (cqin@ee.ualberta.ca)
Sydney Tang (sat@ee.ualberta.ca)
Su-Tarn Lim (sulim@ee.ualberta.ca)