Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

vhdl how is "case" works?

Status
Not open for further replies.

ustinoff

Member level 2
Joined
Mar 6, 2016
Messages
45
Helped
4
Reputation
8
Reaction score
4
Trophy points
8
Location
Russia
Activity points
308
Hello.

The code:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity test is
port
(
     i_arst : in std_logic;
     i_clk  : in std_logic;
     i_data : in std_logic_vector (3 downto 0);
     o_data : out std_logic_vector (3 downto 0)
);
end entity;
 
architecture arch of test is
 
type fsm_state is (S0,S1);
signal fsm_cnt : fsm_state;
 
signal buff_count : unsigned (3 downto 0);
 
signal check_in : std_logic;
 
signal s0_count : unsigned (3 downto 0);
 
signal reg : unsigned(3 downto 0);
 
type buff_type is array (3 downto 0) of unsigned (3 downto 0);
signal buff : buff_type;
 
 
begin
 
fsm_proc : process(i_arst, i_clk)
begin
if i_arst = '1' then 
   s0_count   <= (others=>'0');
   check_in   <= '1';
   fsm_cnt    <= S0;
   reg        <= (others=>'0');
   buff_count <= (others=>'0');
   buff       <= (others=>(others=>'0'));
   elsif rising_edge(i_clk) then
      if (check_in = '1' and to_integer(unsigned(i_data)) >= 8) then
         check_in <= '0';
         s0_count <= (others=>'0');
         fsm_cnt  <= S0;
      elsif check_in = '0' then
         case fsm_cnt is
         
            when S0 =>
                      if s0_count = 15 then
                         fsm_cnt <= S1;
                      else
                         s0_count <= s0_count + 1;
                      end if;
            when S1 =>
                      buff(0) <= unsigned(i_data);
                      buff(3 downto 1) <= buff(2 downto 0);
                      if buff_count = 3 then
                         buff_count <= (others =>'0');
                         check_in <= '1';
                         reg <= buff(3);
                      else
                         buff_count <= buff_count + 1;
                      end if;
            when others => 
                       o_data <= (others=>'0');
        end case;
    end if;
end if;
end process;
 
o_data <= std_logic_vector(reg);
 
 
end arch;



I cannt understand why o_data is always in 'X' condition, reg is always 'zero', but check_in and buff_count works correctly. I read some sources about VHDL, but i didn't find (or didn't understand) how to fix it
 
Last edited by a moderator:

Re: vhdl how is &quot;case&quot; works?

o_data is being driven by two lines of code that are not part of the same process.

Code:
           when others => 
                       [COLOR="#FF0000"]o_data <= (others=>'0');[/COLOR]
        end case;
    end if;
end if;
end process;
 
[COLOR="#FF0000"]o_data <= std_logic_vector(reg);[/COLOR]

This will result in X's anytime the two differ from each other.
Besides this problem o_data in the others branch should never occur (if you wrote your FSM correctly).

Remove the o_data in the others branch it shouldn't be there in the first place. If you put reg in the others clause then it would probably work.

- - - Updated - - -

to avoid the extra assignment step, you could just use/enable VHDL 2008 and directly drive the o_data : out by your FSM. They relaxed the conditions for reading outputs for out (it's now more like buffer).
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top