I am using webPack ISE v 13 to program a Nexys 3 board with the following piece of code and notice completely different behavior by swapping statements in the if elsif statement. In essence, I'm using three pushbuttons on the board: when pressing the first pushbutton btn(0), the state of 8 switches is stored in a register. When I press btn(1), the state of the switches should be displayed in the 8 leds and the leds should keep this state. When I press btn(2), I force all leds to be lit and they should stay this way if neither btn 1 or 2 is pressed. By swapping the actions under the if and elsif for buttons 1 & 2, the behavior changes: the state of the switches is only displayed when I press the corresponding button and once I let go, all LEDs light up.
More than looking for a "this is what you need to make it work", I'm after an explanation of why vhdl behaves so differently from C++ let's say (in this instance where the order wouldn't matter)
Below is the code excerpt; I indicate which lines to comment/uncomment to get behavior 'a' or behavior 'b'.
Behavior 'a':
- when pressing btn(0) the state of the 8 switches loads correctly into the data_reg
- when I press the btn(1), the LEDs are all ON ("111...11")
- if I press btn(2), the LEDs display the data_reg contents
- If no button is pressed, the state of the LEDs is that commanded by the last button press
Behavior 'b':
- when pressing btn(0) the state of the 8 switches loads correctly into the data_reg
- when I press btn(1), the LEDs display the data_reg contents
- if I press btn(2), the LEDs are all ON ("111...11")
- If no button is pressed, all LEDs are ON & the only way to see the contents of the data_reg is to hold btn(1) depressed.
`
process(clk)
begin
if (clk'event and clk='1') thenif (db_btn(0)='1') then --load sw state into data_reg data_reg <= sw; end if;end if; end process;
process(btn,data_reg)
begin
if btn(1)='1' then
data_s2f <= "1111111111111111"; --behvr a; comment this line for behvr b
-- data_s2f <= "00000000" & data_reg; -- uncomment for behvr b; comment for behvr a
elsif btn(2)='1' then -- read
data_s2f <= "00000000" & data_reg; --behvr a; comment this line for behvr b
--data_s2f <= "1111111111111111"; -- uncomment for behvr b; comment for behvr a
end if;
end process;
-- output
led <= data_s2f(7 downto 0); --display data_s2f in LEDs
SIMULATION TESTBENCH
Here is my simulation testbench. Whenever I executed the result for all signals is UUU..UU Any comments would be greatly appreciated:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY ifstmt_tb IS
END ifstmt_tb;
ARCHITECTURE behavior OF ifstmt_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT ram_ctrl_test
PORT(
clk : IN std_logic;
reset : IN std_logic;
sw : IN std_logic_vector(7 downto 0);
btn : IN std_logic_vector(2 downto 0);
led : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal sw : std_logic_vector(7 downto 0) := (others => '0');
signal btn : std_logic_vector(2 downto 0) := (others => '0');
--Outputs
signal led : std_logic_vector(7 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ram_ctrl_test PORT MAP (
clk => clk,
reset => reset,
sw => sw,
btn => btn,
led => led
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
reset <= '1';
sw <= "11001100";
btn<= (others => '0');
wait for 100 ns;
reset <= '0';
wait for clk_period*10;
-- load register
btn<= (0=>'1', others => '0');
wait for clk_period*2;
btn<= (others => '0');
wait for clk_period*10;
-- display with btn 1
btn<= (1=>'1', others => '0');
wait for clk_period*5;
btn<= (others => '0');
wait for clk_period*10;
-- display with btn 2
btn<= (2=>'1', others => '0');
wait for clk_period*5;
btn<= (others => '0');
wait for clk_period*10;
-- change pattern
sw <= "11100111";
wait for clk_period;
-- load register
btn<= (0=>'1', others => '0');
wait for clk_period*2;
btn<= (others => '0');
wait for clk_period*10;
-- display with btn 2
btn<= (2=>'1', others => '0');
wait for clk_period*5;
btn<= (others => '0');
wait for clk_period*10;
-- display with btn 1
btn<= (1=>'1', others => '0');
wait for clk_period*5;
btn<= (others => '0');
-- insert stimulus here
wait;
end process;
END;
db_btnandbtnconnected? - bmkUs for you. - Martin Thompson