My VHDL-Code is functionaly correct, in ModelSim every thing works fine. I tested it with many variations and the code is functionaly correct.
But when I put it on the Altera board it displays a "3" on the 7-segment display, but it should show "0". If I put RESET to "1" it breaks completly and displays only a line in the top segment. My Inputs X, CLK, RESET are connected to the switches. LOAD ist connected to a button and DIGIT to the 7-segment display.
It should have a clock signal as I swtich the CLK-switch.
Here my full code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET: IN std_logic;
LOAD: IN std_logic;
DIGIT: OUT std_logic_vector(6 DOWNTO 0) := "1111110";
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state: statetype:=s0;
SIGNAL next_state: statetype;
SIGNAL counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0):= (OTHERS => '0');
SIGNAL so: std_logic := 'U';
-------------------Aktualisierung des Zustandes--------------------------------
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
---------------------Counter---------------------------------------------------
COUNT: PROCESS (state, RESET)
BEGIN
IF (RESET = '1') THEN
counter <= (OTHERS => '0');
ELSIF (state = s4) THEN
counter <= counter + '1';
END IF;
END PROCESS COUNT;
-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSIF (CLK'event and CLK='1') THEN
so <= temp(15);
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END PROCESS PISO;
-------------------Zustandsabfrage und Berechnung------------------------------
STATE_CAL: PROCESS (so,state)
BEGIN
next_state <= state;
Y <= '0';
CASE state IS
WHEN s0 =>
IF so = '1' THEN
next_state <= s0 ;
END IF;
WHEN s1 =>
IF so = '1' THEN
next_state <= s1;
END IF;
WHEN s2 =>
IF so = '0' THEN
next_state <= s3 ;
END IF;
WHEN s3 =>
IF so = '0' THEN
next_state <= s0 ;
ELSE
next_state <= s4 ;
END IF;
WHEN s4 =>
Y <= '1';
IF so = '0' THEN
next_state <= s0;
ELSE
next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
-------------------7 Segment---------------------------------------------------
SEVEN_SEG: PROCESS (counter)
BEGIN
CASE counter IS
WHEN "000" => DIGIT <= "1111110";
WHEN "001" => DIGIT <= "0110000";
WHEN "010" => DIGIT <= "1101101";
WHEN "011" => DIGIT <= "1111001";
WHEN "100" => DIGIT <= "0110011";
WHEN "101" => DIGIT <= "1011011";
WHEN OTHERS => NULL;
END CASE;
END PROCESS SEVEN_SEG;
END SEQ;
I am pretty new to VHDL and am pretty sure it hase to do something with the timings, cause the functional part should be fine, as already said.
Hope for some hints, tips or even solutions.
EDIT: new code without LOAD, is this a valid idea? (non the less the whole code is not working on the FPGA....)
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET: IN std_logic;
LOAD: IN std_logic;
DIGIT: OUT std_logic_vector(0 TO 6) := "0000001";
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state: statetype:=s0;
SIGNAL next_state: statetype;
SIGNAL counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0):= (OTHERS => '0');
SIGNAL so: std_logic := 'U';
-------------------Aktualisierung des Zustandes--------------------------------
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
---------------------Counter---------------------------------------------------
COUNT: PROCESS (state, RESET)
BEGIN
IF (RESET = '1') THEN
counter <= (OTHERS => '0');
ELSIF (state = s4) THEN
counter <= counter + '1';
END IF;
END PROCESS COUNT;
-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (CLK'event and CLK='1') THEN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSE
so <= temp(15);
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END IF;
END PROCESS PISO;
-------------------Zustandsabfrage und Berechnung------------------------------
STATE_CAL: PROCESS (so,state)
BEGIN
next_state <= state;
Y <= '0';
CASE state IS
WHEN s0 =>
IF so = '1' THEN
next_state <= s1 ;
END IF;
WHEN s1 =>
IF so = '1' THEN
next_state <= s2;
END IF;
WHEN s2 =>
IF so = '0' THEN
next_state <= s3 ;
END IF;
WHEN s3 =>
IF so = '0' THEN
next_state <= s0 ;
ELSE
next_state <= s4 ;
END IF;
WHEN s4 =>
Y <= '1';
IF so = '0' THEN
next_state <= s0;
ELSE
next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
-------------------7 Segment---------------------------------------------------
SEVEN_SEG: PROCESS (counter)
BEGIN
CASE counter IS
WHEN "000" => DIGIT <= "0000001";
WHEN "001" => DIGIT <= "1001111";
WHEN "010" => DIGIT <= "0010010";
WHEN "011" => DIGIT <= "0000110";
WHEN "100" => DIGIT <= "1001100";
WHEN "101" => DIGIT <= "0100100";
WHEN OTHERS => DIGIT <= "0000001";
END CASE;
END PROCESS SEVEN_SEG;
END SEQ;
EDIT: This is now my version. It will still show a "0" no matter what I do.
- I would assume it has to do with the COUNT and counter.
- should i realize this as synchronous too?
- Is the numeric and unsigned really that big of a problem? We did it that way at university.
- And will it work when i put LOAD onto a slide switch???
Best regards Adrian