23
A Simple Microcontroller VHDL Tutorial R. E. Haskell and D. M. Hanna T6: VHDL State Machines

A Simple Microcontroller VHDL Tutorial R. E. Haskell and D. M. Hanna T6: VHDL State Machines

  • View
    249

  • Download
    6

Embed Size (px)

Citation preview

A Simple Microcontroller

VHDL Tutorial

R. E. Haskell and D. M. Hanna

T6: VHDL State Machines

The T8X Microcontroller

mux4

Tregclkclr

Nregclkclr

ALU

T

N

tload

nload

tin

Tcontrol

Trom6

inc

M

P

nload

tload

instr

msel(1:0)

DigDisplay

A(3:0) AtoG(6:0)

SW(1:8)

LD(1:8)

clk

clr

T

T N

digload

alusel(1:0)

BTN(1:4)

iregclkclr iload

digload

iloadalusel(1:0)

inc

BTN(1)

osc_4k

clr

clk

M

clr

clk

PCclkclr pload

BTN(1:4)

pload

y

PC.vhdlibrary IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;

entity PC is port ( d: in STD_LOGIC_VECTOR (7 downto 0); clr: in STD_LOGIC; clk: in STD_LOGIC; inc: in STD_LOGIC; pload: in STD_LOGIC; q: out STD_LOGIC_VECTOR (7 downto 0) );end PC;

architecture PC_arch of PC isbeginprocess (clk, clr)variable COUNT: STD_LOGIC_VECTOR (7 downto 0);begin if clr = '1' then COUNT := "00000000"; q <= COUNT; elsif clk'event and clk='1' then if pload = '0' then if inc = '1' then COUNT := COUNT + 1; end if; else COUNT := d; end if;

q <= COUNT; end if;end process;end PC_arch;

Tcodes.vhd

package tcodes is subtype opcode is std_logic_vector(7 downto 0); -- Register instructions --WHYP WORDS constant nop: opcode := X"00"; -- NOP constant dup: opcode := X"01"; -- DUP -- ALU instructions constant plus: opcode := X"10"; -- + constant plus1: opcode := X"11"; -- 1+ constant invert: opcode := X"12"; -- INVERT constant twotimes: opcode := X"13"; -- 2*

-- Return Stack, Memory Access, and I/O instructions constant swfetch: opcode := X"31"; -- SW@ constant digstore: opcode := X"32"; -- DIG!

-- Transfer instructions constant jmp: opcode := X"40"; -- GOTO constant jnbtn4: opcode := X"41"; -- WAIT_BTN2_UP constant jbtn4: opcode := X"42"; -- IF_BTN4 end tcodes;

fetch

execexec_fetch

M(6)=‘1’M(6)=‘0’

M(6)=‘0’ M(6)=‘1’

Tcontrol

Trom6

inc

M

P

nload

tload

instr

BTN(1:4)

iregclkclr iload

digload

iloadalusel(1:0)

inc

M

clr

clk

PCclkclr pload

pload

-- Transfer instructions constant jmp: opcode := X"40"; -- GOTO constant jnbtn4: opcode := X"41"; -- WAIT_BTN2_UP constant jbtn4: opcode := X"42"; -- IF_BTN4

VHDLFinite State Machine

Sta

te R

egis

ter

C1x(t)

s(t+1)

s(t)z(t)

clk

clr

present state

nextstate

C2

process(clk, clr)

process(present_state, x)

process(present_state, x)

Tcontrol State Machine

Sta

te R

egis

ter

C1

instr

s(t+1)

s(t)

clk

clr

current state

nextstate

C2

process(clk, clr)

process(current_state, M)

process(current_state, instr)

M

architecture Tcontrol_arch of Tcontrol is type state_type is (fetch, exec, exec_fetch); signal current_state, next_state: state_type;

synch: process(clk, clr) begin if clr = '1' then current_state <= fetch; elsif (clk'event and clk = '1') then current_state <= next_state; end if; end process synch;

C1: process(current_state, M)begin case current_state is when fetch => if M(6) = ‘1’ then next_state <= exec; else next_state <= exec_fetch; end if; when exec_fetch => if M(6) = ‘1’ then next_state <= exec; else next_state <= exec_fetch; end if; when exec => next_state <= fetch; end case;end process C1;

fetch

execexec_fetch

M(6)=‘1’M(6)=‘0’

M(6)=‘0’ M(6)=‘1’

Tcontrol State Machine

Sta

te R

egis

ter

C1

instr

s(t+1)

s(t)

clk

clr

current state

nextstate

C2

process(clk, clr)

process(current_state, M)

process(current_state, instr)

M

C2: process(instr, current_state) begin alusel <= "00"; msel <= "00"; pload <= '0'; tload <= '0'; nload <= '0'; digload <= '0'; inc <= '1'; iload <= '0'; if (current_state = fetch) or

(current_state = exec_fetch) then iload <= '1'; -- fetch next instruction end if; if (current_state = exec) or

(current_state = exec_fetch) then case instr is

when nop => null;

when dup => nload <= '1';

when plus => tload <= '1'; when plus1 => tload <= '1'; alusel <= "01";

when invert => tload <= '1'; alusel <= "10";

when twotimes => tload <= '1'; alusel <= "11";

when swfetch =>

tload <= '1'; msel <= "01";

when digstore => digload <= '1'; when jmp => pload <= '1'; inc <= '0'; when jnbtn4 => pload <= not BTN(4); inc <= BTN(4); when jbtn4 => pload <= BTN(4); inc <= not BTN(4);

when others => null;

end case; end if; end process C2;

T6 Lab ExerciseMultiply switch setting by 10 and display

hex result on 7-segment display.

BEGIN

WAIT_BTN4 \ wait to press BTN4

SW@ \ read SW(1:8) n

DIG! \ 7-segment display

WAIT_BTN4 \ n

2* \ 2n

DUP \ 2n 2n

2* \ 2n 4n

2* \ 2n 8n

+ \ 10n

DIG! \ 7-segment display

AGAIN ;

Trom6.vhd

library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;use work.tcodes.all;

entity Trom6 is port ( addr: in STD_LOGIC_VECTOR (7 downto 0); M: out STD_LOGIC_VECTOR (7 downto 0) );end Trom6;

architecture Trom6_arch of Trom6 issubtype tword is std_logic_vector(7 downto 0);type rom_array is array (0 to 18) of tword;constant rom: rom_array := (

JBTN4, X"00", -- X"00" wait for BTN4 upJNBTN4, X"02", -- X"02" wait for BTN4SWFETCH, -- X"04" push switchesdigstore, -- X"05" displayJBTN4, X"06", -- X"06" wait for BTN4 upJNBTN4, X"08", -- X"08" wait for BTN4twotimes, -- X"0A" 2*DUP, -- X"0B" DUPtwotimes, -- X"0C" 2*twotimes, -- X"0D" 2*plus, -- X"0E" +digstore, -- X"0F" displayJMP, X"00", -- X"10" GOTO 0X"00" -- X"12");

T6 Lab Exercise

File T6comp.vhd is a package that contains the component declarations for all components in the T8X microcontroller.

File T6main.vhd is the top-level design of the T8X microcontroller.

T6 Lab Exercise:The T8X Microcontoller

mux4

Tregclkclr

Nregclkclr

ALU

T

N

tload

nload

tin

Tcontrol

Trom6

inc

M

P

nload

tload

instr

msel(1:0)

DigDisplay

A(3:0) AtoG(6:0)

SW(1:8)

LD(1:8)

clk

clr

T

T N

digload

alusel(1:0)

BTN(1:4)

iregclkclr iload

digload

iloadalusel(1:0)

inc

BTN(1)

osc_4k

clr

clk

M

clr

clk

PCclkclr pload

BTN(1:4)

pload

y

T6main.vhd

library IEEE;use IEEE.std_logic_1164.all;use work.T6comp.all;

entity T6main is port ( SW: in STD_LOGIC_VECTOR (1 to 8); BTN: in STD_LOGIC_VECTOR (1 to 4); LD: out STD_LOGIC_VECTOR (1 to 8); AtoG: out STD_LOGIC_VECTOR (6 downto 0); A: out STD_LOGIC_VECTOR (3 downto 0) );end T6main;

T6main.vhd (cont.)architecture T6main_arch of T6main is

signal tin, T, N, y, P, M, instr: std_logic_vector(7 downto 0);

signal clr, clk: std_logic;signal pload, iload, tload, nload,

digload, inc: std_logic;signal msel, alusel : std_logic_vector(1 downto 0);signal GND: std_logic_vector(3 downto 0);begin

begin GND <= "0000"; U0: mux4 port map (a => y, b =>SW, c(3 downto 0) => BTN, c(7 downto 4) => GND, d => M, sel => msel, y => tin); Treg: reg port map (d => tin, load =>tload, clr => clr, clk =>clk, q => T); Nreg: reg port map (d => T, load => nload, clr => clr, clk =>clk, q => N); U1: alu port map (a => T, b => N, sel => alusel, y => y); U2: digdisplay port map (T => T, N => N, digload => digload, clr => clr, clk => clk, A => A, AtoG => AtoG);

T6main.vhd (cont.)

U3: PC port map (d => M, clr => clr, clk => clk, pload => pload, inc => inc, q => P); U4: Trom6 port map (addr => P, M => M); ireg: reg port map (d => M, load => iload, clr => clr, clk =>clk, q => instr); U5: Tcontrol port map (instr => instr, M => M, clr => clr, clk => clk, BTN => BTN, alusel => alusel, msel => msel, inc => inc, pload => pload, tload => tload, nload => nload, digload => digload, iload => iload); U6: osc_4k port map (clk => clk); LD <= SW; clr <= BTN(1);end T6main_arch;

T6main.vhd (cont.)