• Aucun résultat trouvé

Translating the State Flow Diagram to VHDL

Dans le document Programmable VHDL (Page 151-156)

The state flow diagram can be translated easily to a series of cases in a CASE-WHEN construct as follows (we are disregarding the synchronous reset for now):

case present_state is

when idle => if (bus_id = "11110011") then next_state <= decision;

else

As you can see, the section of code inside the state_comb process falls out directly from the bubble diagram: Each state is simply one of the cases in the CASE-WHEN construct, and all of the transitions from states are documented in IF-THEN statements. Take state decision, for example:

Examining the state flow diagram, you see that there are two transitions from this state depending on the value of read_write. If read_write is asserted (a read operation), then nexCstate is read1, otherwise nexCstate is write. The remaining states are likewise coded.

This state machine requires a synchronous reset. Rather than specifying the reset condition in each of the transitions, we can include an IF-THEN construct at the beginning of the process in order to place

the machine in the idle state if reset is asserted. If reset is not asserted, then the normal state transitioning occurs. The code for this is as follows:

state_comb:process(reset, present_state, burst, read_write, ready) begin if (reset = 'I') then

next_state <= idle;

else

case present_state is end case;

end if;

The complete code for the memory controller state machine is shown below as Listing 5-2.

library ieee; ,

use ieee.std_logic_1164.all;

entity memory_controller is port

) ;

reset, read_write, ready, burst, clk

in std_logic_vector(7 downto 0);

out std_logic;

out std_logic_vector(l downto 0)

architecture state_machine of memory_controller is

type StateType is (idle, decision, read1, read2, read3, read4, write);

signal present_state, next_state : StateType;

begin

state_comb:process(reset, bus_id, present_state, burst, read_write, ready) begin

if (reset = 'I') then next_state <= idle;

else

case present_state is

when idle => if (bus_id = "11110011") then next_state <= decision;

else

140

end process state_comb;

state_clocked:process(clk) begin if (clk'event and clk

=

'1') then

present_state <= next_state;

end if;

end process state_clocked;

-- combinatorially decoded outputs with present_state select

oe <= '1' when read1

I

read2

I

read3

I

read4, '0' when others;

we <= '1' when present_state write else '0';

with present_state select addr <= "01" when read2,

"10" when read3,

"11" when read4,

"00" when others;

end state_machine; --architecture Listing 5-2 Memory controller

Listing 5-2 illustrates a design that uses one process to define the combinational logic for state transitioning and a second process to synchronize the next-state assignment to the clock. This is a common and easy way to describe state machines, especially for machines that will be implemented in a PLD. A PLD architecture resembles this design structure because it consists of a product-term array feeding flip-flops. See Figure 5-6 for an illustration of this concept. The decoding of presenCstate and inputs is performed in the combinatorial block of the PLD just as it is described in the combinatorial process in the code. Synchronization of nexCstate is described in the state_clocked process, referring to a bank of registers such as those in the PLD.

The state transitions defined in the state_comb process are fairly easy to follow, but you may be wondering about the state registers and state encoding. With this design, we chose to create a type called StateType, an enumerated type consisting of the state names: idle, decision, read1, read2, read3, and read4, and write. If you use an enumerated type, the state encoding is determined by the synthesis software unless you explicitly declare the state encoding by using an attribute, directive, command line switch, or GUI (graphical user interface) option. As a default, most synthesis tools use a sequential coding, in which case three bits are used for the seven states: idle is "000", decision is

"001", read1 is "010", etc. We'll show how to choose your own state encoding later in the chapter.

Alternatively, we could have declared individual bits as state registers; however, using an enumerated type simplifies state transition coding and makes the code easier to comprehend and maintain.

Outputs for this design are defined with concurrent signal assignments using WITH-SELECT and WHEN-ELSE constructs. The outputs are functions of the present state only (a Moore machine) and

can be defined quickly by making use of StateType. .

If an asynchronous reset is desired instead of a synchronous reset, then you can use the asynchronous reset template discussed in the previous chapter by rewriting the state_clocked process of Listing 5-2 as follows:

state_clocked:process(clk,reset) begin if reset= '1' then

present_state <= idle;

elsif (clk'event and clk = '1') then present_state <= next_state;

end if;

end process state_clocked;

This state machine is one that would be difficult to design and maintain using a traditional design methodology. For instance, if the polarity of ready, burst, or read_write is reversed, updating the VHDL 'code is a simple task. Regenerating next-state design equations is not, because this design has many combinations of input. A comparison of the relative ease of design is left as an exercise for the reader!

141

(a)

INPUTS

(b)

INPUTS

~

142

NEXT STATE

CURRENT STATE

Corn bin a torial Logic

... -... -... ~

----.---~~

---0---::;::;----

./'~

--D-~~

~, ---D---~

---0--- .----///"

-~?

~

---[)--.~

---D--- -

~, .. ~

----o----~---. / ' ' ' '

-.--~/----~

CURRENT STATE

CLK'EVE NT:

'iliid:

[G.LK.~

•• 'l"

Flip-Flops

,.JLE.L.-NEXT STATE2 0

Il

f.---J~

~

,.JLE.L.-NEXT STATE! 0

Il

f.---Jf>

~

....Jl£.£...-NEXT STATEO 0

Il

'--->

Figure 5-6 Comparing (a) the code structure of Listing 5-2 to (b) the architecture of a PLD

CUR r:lENT STAT]';.2

CUR ENT STATE.!

CUR NT STATEQ

Dans le document Programmable VHDL (Page 151-156)