a simple microcontroller vhdl tutorial r. e. haskell and d. m. hanna t6: vhdl state machines
Post on 19-Dec-2015
249 views
TRANSCRIPT
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.)