Forum Discussion
Altera_Forum
Honored Contributor
14 years agoStrange Behavior when using case statement on EPM3128A
I have been having a problem with a project that I am doing and have asked many people in the office to no eval.
I am using an Altera EPM3128A Device with a GCLK1 speed of 24MHz, I then devide this down in the device to a very slow speed ( >1Hz) so that I can see the behavior of some LED's that are attached to the device. I have a case statement that switches a green LED on and a Red one off and advances the case statement. The next case switches the red LED on and green LED off, the next case is then set to the original case. (The LEDs are active 0) The problem that I am having is that on startup of the device, both LED's are coming on together. These is never a state in the program when both of the LED's are on together. The program then runs as expected. If I set one off the states so that both of the LED's are off then on startup only the LED that is turned on during one of the states will display. Again the program will then run as expected I have attached my code and would be grateful of any pointers that you can give or any explanations as to what is going on.library ieee;
use ieee.std_logic_1164.all;
entity USBDownloader is
generic ( CLK_DIVIDER_6 : integer :=20000000);--------DO NOT CHANGE--------
port(
----------------------CLOCKS--------------------------------------
SYS_CLK_IN : in std_logic;
CLK_6MHz : out std_logic;
ULED : out std_logic;
RLED : out std_logic
);
end entity USBDownloader;
architecture rtl of USBDownloader is
type case_counter_type is (a, b, c);
-- Declare Constants and Variables
signal CLK_TEMP_6 : std_logic := '0';
signal CNT_6 : integer range 0 to 20000000 := 0 ;
signal case_counter : case_counter_type := a;
begin
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
process ( CLK_TEMP_6)
begin
if rising_edge (CLK_TEMP_6) then
case case_counter is
when a =>
ULED <= '0';----GREEN LED ON-----
RLED <= '1';
case_counter <= b;
when b =>
ULED <= '1';
RLED <= '0';-------RED LED ON-----
case_counter <= a;
when others =>
null;
end case;
END IF;
END PROCESS;
process (SYS_CLK_IN)
begin
if (SYS_CLK_IN'event and SYS_CLK_IN='1') then
CNT_6 <= CNT_6 + 1;
if ( CNT_6 = CLK_DIVIDER_6-1 ) then
CLK_TEMP_6 <= not CLK_TEMP_6;
CNT_6 <= 0;
end if;
end if;
end process;
CLK_6MHz <= CLK_TEMP_6 ;
---------------------------------------------------------------------------------------------------------------------------------
end rtl; Many thanks5 Replies
- Altera_Forum
Honored Contributor
The LEDS are connected to registers, that are powering up in a low state, turning both LEDs on. You need to specify a power up value via attributes or use an async reset to get the power on value (the synthesisor will usually use the async reset value as the power value, even if you tie the reset to '0')
- Altera_Forum
Honored Contributor
If I define both of the LED outputs as := '1'; then the problem still persists
ULED : out std_logic :='1'; RLED : out std_logic :='1' - Altera_Forum
Honored Contributor
This does not help.
You have to define separate register signals for your LED's and give these signals a default value.LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY USBDownloader IS GENERIC ( CLK_DIVIDER_6 : integer := 20000000 --------DO NOT CHANGE-------- ); PORT ( ----------------------CLOCKS-------------------------------------- SYS_CLK_IN : IN std_logic; CLK_6MHz : OUT std_logic; ULED : OUT std_logic; RLED : OUT std_logic ); END ENTITY USBDownloader; ARCHITECTURE rtl OF USBDownloader IS TYPE case_counter_type IS (a, b, c); -- Declare Constants and Variables SIGNAL CLK_TEMP_6 : std_logic := '0'; SIGNAL CNT_6 : integer RANGE 0 TO 20000000 := 0; SIGNAL case_counter : case_counter_type := a; SIGNAL uled_r : std_logic := '1'; SIGNAL rled_r : std_logic := '1'; BEGIN ------------------------------------------------------------------------------- PROCESS (CLK_TEMP_6) BEGIN IF rising_edge (CLK_TEMP_6) THEN CASE case_counter IS WHEN a => uled_r <= '0'; ----GREEN LED ON----- reld_r <= '1'; case_counter <= b; WHEN b => uled_r <= '1'; rled_r <= '0'; -------RED LED ON----- case_counter <= a; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS; PROCESS (SYS_CLK_IN) BEGIN IF (SYS_CLK_IN'EVENT AND SYS_CLK_IN = '1') THEN CNT_6 <= CNT_6 + 1; IF (CNT_6 = CLK_DIVIDER_6-1) THEN CLK_TEMP_6 <= NOT CLK_TEMP_6; CNT_6 <= 0; END IF; END IF; END PROCESS; CLK_6MHz <= CLK_TEMP_6; ------------------------------------------------------------------------------- ULED <= uled_r; RLED <= rled_r; END rtl; - Altera_Forum
Honored Contributor
Again that was another thing that I tried today and the same thing happened.
- Altera_Forum
Honored Contributor
Can you explain this statement a little bit more clearly? -
"If I set one off the states so that both of the LED's are off then on startup only the LED that is turned on during one of the states will display. Again the program will then run as expected " Also, at startup do both the LEDs just flash on for a short period and then start exhibiting normal behavior? Is there a pulldown on those pins? You shouldn't use clocks generated in a process like you have (CLK_TEMP_6). The behavior can be odd. Use the fast clock SYS_CLK_IN to clock the process and then create a pulse that goes high for 1clk cycle every 1Mhz or whatever (similar to how you generated CLK_TEMP_6) and use it as an enable signal instead. Something like this process( SYS_CLK_IN ) begin if rising_edge( SYS_CLK_IN ) then if( one_mhz_pulse = '1' ) then case .... end if;[/INDENT] endif;[/INDENT] end process;