EmbDev.net

Forum: FPGA, VHDL & Verilog how to use clk in fsm


von daniel (Guest)


Rate this post
useful
not useful
I want to build a final state machine embodies eight numbers and then 
she proceeded to tell the eighth.
For example if  the  eight number  is four I want the machine extract 
four pulses of 1 clock cycle difference between between pulses and then 
wait another 10 clock cycles and then switches to the next state( and in 
the next do the same thing).
The problem that he dosent let me use the clock in the states ..
Does anyone have an idea what to do?


The code
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.std_logic_arith.all;
5
6
entity pulsim is 
7
   port( 
8
    resetN, clk : in std_logic;
9
    da         : in std_logic_vector(3 downto 0) ;
10
        db         : in std_logic_vector(3 downto 0) ;
11
        dc         : in std_logic_vector(3 downto 0) ;
12
        dd         : in std_logic_vector(3 downto 0)  ;
13
        de         : in std_logic_vector(3 downto 0)  ;
14
        df         : in std_logic_vector(3 downto 0)  ;
15
        dg         : in std_logic_vector(3 downto 0)  ;
16
        dh         : in std_logic_vector(3 downto 0)  ;
17
    sinus      : out  std_logic);
18
end pulsim ; 
19
architecture behavioral of pulsim is 
20
21
22
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
23
signal current_s,next_s: state_type;
24
signal countera : std_logic_vector(4 downto 0) :=dh &'0' ;
25
signal counterb : std_logic_vector(4 downto 0) :="01010" ;
26
signal cinout   : std_logic ;
27
28
begin 
29
   
30
process ( resetN , clk)
31
   begin
32
    if resetN = '0' then
33
        current_s <= s0;
34
  elsif (rising_edge(clk)) then
35
  current_s <= next_s;
36
  end if;
37
   end process;
38
39
40
process (current_s,dh,clk)
41
begin
42
  sinus <= cinout ;
43
  case current_s is
44
     when s0 =>        --when current state is "s0"
45
     if(dh ="1111") then
46
      cinout <= '0';
47
      next_s <= s0;
48
   else
49
    if clk='1' then
50
      if countera /= "00000" then
51
        countera <= countera-"00001";
52
        cinout<= not(cinout);
53
        counterb<="01010";
54
      
55
      elsif (countera = "00000") and (counterb/="00000") then
56
          counterb <= counterb-"00001";
57
          cinout <= '0' ;
58
      else
59
      counterb<="01010";
60
      countera<=dg &'0';
61
      next_s <= s1;
62
      end if;
63
    end if;
64
  end if;
65
  when s1 => 
66
    
67
    if rising_edge(clk) then
68
      if countera /= "00000" then
69
        countera <= countera-"00001";
70
        cinout <= not (cinout) ;
71
        counterb<="01010";
72
      
73
      elsif (countera = "00000") and (counterb/="00000") then
74
          counterb <= counterb-"00001";
75
          cinout <= '0' ;
76
      else
77
      counterb<="01010";
78
      countera<=df &'0';
79
      next_s <= s2;
80
      end if;
81
    end if;        
82
      
83
      
84
  when s2 => 
85
    
86
    if rising_edge(clk) then
87
      if countera /= "00000" then
88
        countera <= countera-"00001";
89
        cinout <= not (cinout) ;
90
        counterb<="01010";
91
      
92
      elsif (countera = "00000") and (counterb/="00000") then
93
          counterb <= counterb-"00001";
94
          cinout <= '0' ;
95
      else
96
      counterb<="01010";
97
      countera<=de &'0';
98
      next_s <= s3;
99
      end if;
100
    end if;  
101
    
102
    when s3 => 
103
    
104
    if rising_edge(clk) then
105
      if countera /= "00000" then
106
        countera <= countera-"00001";
107
        cinout <= not (cinout) ;
108
        counterb<="01010";
109
      
110
      elsif (countera = "00000") and (counterb/="00000") then
111
          counterb <= counterb-"00001";
112
          cinout <= '0' ;
113
      else
114
      counterb<="01010";
115
      countera<=dd &'0';
116
      next_s <= s4;
117
      end if;
118
    end if;              
119
    
120
    when s4 => 
121
    
122
    if rising_edge(clk) then
123
      if countera /= "00000" then
124
        countera <= countera-"00001";
125
        cinout <= not (cinout) ;
126
        counterb<="01010";
127
      
128
      elsif (countera = "00000") and (counterb/="00000") then
129
          counterb <= counterb-"00001";
130
          cinout <= '0' ;
131
      else
132
      counterb<="01010";
133
      countera<=dc &'0';
134
      next_s <= s5;
135
      end if;
136
    end if;  
137
    
138
    when s5 => 
139
    
140
    if rising_edge(clk) then
141
      if countera /= "00000" then
142
        countera <= countera-"00001";
143
        cinout <= not (cinout) ;
144
        counterb<="01010";
145
      
146
      elsif (countera = "00000") and (counterb/="00000") then
147
          counterb <= counterb-"00001";
148
          cinout <= '0' ;
149
      else
150
      counterb<="01010";
151
      countera<=db &'0';
152
      next_s <= s6;
153
      end if;
154
    end if;                  
155
    
156
    
157
    when s6 => 
158
    
159
    if rising_edge(clk) then
160
      if countera /= "00000" then
161
        countera <= countera-"00001";
162
        cinout <= not (cinout) ;
163
        counterb<="01010";
164
      
165
      elsif (countera = "00000") and (counterb/="00000") then
166
          counterb <= counterb-"00001";
167
          cinout <= '0' ;
168
      else
169
      counterb<="01010";
170
      countera<=da &'0';
171
      next_s <= s7;
172
      end if;
173
    end if;    
174
    when s7 => 
175
    
176
    if rising_edge(clk) then
177
      if countera /= "00000" then
178
        countera <= countera-"00001";
179
        cinout<= not (cinout) ;
180
        counterb<="01010";
181
      
182
      elsif (countera = "00000") and (counterb/="00000") then
183
          counterb <= counterb-"00001";
184
          cinout <= '0' ;
185
      else
186
      counterb<="01010";
187
      countera<=dh &'0';
188
      next_s <= s0;
189
      end if;
190
    end if;            
191
         
192
  
193
  end case;
194
end process;
195
196
end behavioral;

: Edited by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
daniel wrote:
> a final state machine
In fact its a "finite" state machine. That means: this machine only has 
a limited number of states. The opposite would be a machine with 
uncountable sates, a machine with "infinte states"...

> The problem that he dosent let me use the clock in the states ..
> Does anyone have an idea what to do?
You have a VERY, VERY strange way of using a clock. Can you show me any 
example doing it a similar way?

No?

Correct. The only way to use a clock for synthesis is at the very 
beginning of a process. And additionally you should (for beginners 
"must") have only one clock sensitive to the same edge throughout.

And now simply have a look how others did that thing with those FSM.
A hint: a "rising_edge(clk)" involves a flipflop. And that's the state 
memory.
Additionally you need some logic to calculate the next state.
That's all...


One is fairly easy to see: you did programming in C previously. And now 
you want to "program" with VHDL. But if that was a "programming 
language", then it would be VHPL...
So up to now you have the wrong way of thinking: you think in software, 
but you must think in hardware. And then you can "describe" your 
thoughts.


BTW: did you see the "formatting options" for VHDL code a few lines 
above the text edit box? Use it. Its magic...

: Edited by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Initialization with a non constant values is NOT synthesizeable (the 
init value can't be predicted by the synthesizer!!!):
1
signal countera : std_logic_vector(4 downto 0) :=dh &'0' ;


Now lets have a second look at your code. And there its easy to see the 
usual beginners problems with the 2-process-FSM: you have a 
combinatorial process and a process for the flipflops. But when you want 
to count, then that counter itself is (the simplest way of) a FSM. And 
each FSM has: flipflops and logic. And as that counter is an FSM also, 
it must have flipflops and logic.
As i said previously you will get flipflops when you use a 
"rising_edge()" (or a "falling_edge()" or a "'event"). Yo tried to 
involve that into your combinatorial process, and now you have two 
processes generating flipflops. Thats not the intention of writing a 
2-process-FSM.

What to do now?
1. use the 2-process-FSM further on.
Then you will have to kick out the clk of the combiunatorial process, 
and to invoke some signals like countera_next and counterb_next. And you 
will have to calculate the "next" value in the combinatorial process and 
you will have to transfer the "next" counter values to countera and 
counterb in the clocked process.

2. use the 1-process-FSM.
Then you will have to kich off those "next" values and you will have to 
invoke the clock to the combinatorial process.

Heres your problem analyzed:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Try it with Google translator, its German...

As a result it will look this way as a 1-process-FSM:
1
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
2
signal state: state_type;
3
4
signal countera : std_logic_vector(4 downto 0) :="00000" ;
5
signal counterb : std_logic_vector(4 downto 0) :="01010" ;
6
signal cinout   : std_logic ;
7
8
begin 
9
   
10
sinus <= cinout ;
11
12
process (clk)
13
begin
14
  if (rising_edge(clk)) then  -- the one and only clock
15
16
   case state is
17
   when s0 =>        --when current state is "s0"
18
     if(dh ="1111") then
19
      cinout <= '0';
20
      next_s <= s0;
21
     else
22
      if countera /= "00000" then
23
        countera <= countera-"00001";
24
        cinout<= not(cinout);
25
        counterb<="01010";
26
      
27
      elsif (countera = "00000") and (counterb/="00000") then
28
          counterb <= counterb-"00001";
29
          cinout <= '0' ;
30
      else
31
      counterb<="01010";
32
      countera<=dg &'0';
33
      next <= s1;
34
      end if;
35
     end if;
36
37
   when s1 => 
38
      if countera /= "00000" then
39
        countera <= countera-"00001";
40
        cinout <= not (cinout) ;
41
        counterb<="01010";
42
      
43
      elsif (countera = "00000") and (counterb/="00000") then
44
          counterb <= counterb-"00001";
45
          cinout <= '0' ;
46
      else
47
        counterb<="01010";
48
        countera<=df &'0';
49
        next <= s2;
50
      end if;
51
    
52
    :      
53
    :      
54
55
    when s7 => 
56
      if countera /= "00000" then
57
        countera <= countera-"00001";
58
        cinout<= not (cinout) ;
59
        counterb<="01010";
60
      
61
      elsif (countera = "00000") and (counterb/="00000") then
62
          counterb <= counterb-"00001";
63
          cinout <= '0' ;
64
      else
65
        counterb<="01010";
66
        countera<=dh &'0';
67
        next_s <= s0;
68
      end if;
69
  
70
    end case;
71
  end if; -- the one and only clock
72
end process;
73
74
end behavioral;

BTW: I strongly recommend to use the numeric_std lib instead of that old 
Synopsis libs...
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std
I also strongly recommend using integers for counting. Its FAR WAY 
easier to read this here:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
:
5
:
6
signal countera : integer range 0 to 10 := 0;
7
signal counterb : integer range 0 to 10 := 10;
8
:
9
    when s7 => 
10
      if countera /= 0 then
11
        countera <= countera-1;
12
        cinout   <= not (cinout) ;
13
        counterb <= 10;
14
      elsif (countera = 0 and (counterb /= 0) then
15
        counterb <= counterb-1;
16
        cinout   <= '0' ;
17
      else
18
        counterb <= 10;
19
        countera <= to_integer(unsigned(dh))*2;
20
        next_s   <= s0;
21
      end if;
22
:
23
:
And as you see I also strongly recommend to use indetion to get an 
easily readable code...

: Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.