
- •Технічне завдання
- •Опис проекту
- •1. Структура мікрокомп`ютера
- •2 Зовнішній інтерфейс мікропроцесора Gnome
- •2.1 Порти мікропроцесора
- •2.2 Інтерфейс з зовнішньою пам'яттю
- •2.3 Переведення мікропроцесора до початкового стану
- •3. Програмна модель мікропроцесора
- •3.1 Програмно-доступні регістри
- •3.2 Множина інструкцій мікропроцесора
- •4. Внутрішня структура мікропроцесора
- •4.1 Інформаційний тракт мікропроцесора Gnome
- •1. Восьмирозрядний мультиплексор mux1
- •2. Програмно-доступні регістри pc,pc1, z, c, acc
- •3. Регістр інструкцій ir
- •4. Семирозрядний мультиплексор mux2 та суматор sm
- •5. Чотирирозрядний мультиплексор mux3
- •6. Арифметико-логічний пристрій
- •7. Регістровий файл
- •8. Допоміжні елементи
- •4.2 Цикли виконання команд
- •1. Цикл вибирання інструкцій (Instruction Fetch cycle -if)
- •2. Цикл декодування інструкції/вибирання операнда з регістрового файлу (Instruction decode/register fetch cycle - id)
- •3. Цикл виконання (Execute cycle - ex)
- •4.3 Керуючий автомат
- •1. Цикл вибирання інструкцій (Instruction Fetch cycle -if)
- •3. Цикл виконання (Execute cycle - ex)
- •Висновки
- •Список літератури
- •Додаток
Список літератури
Методичні вказівки до циклу лабораторних робіт з курсу «Теорія та проектування комп`ютерних систем та мереж» для підготовки спеціалістів та магістрів на базі напрямку «Комп`ютерна інженерія»/Укл.Дунець Б.Р., Мельник А.О., Троценко В.В. – Львів: Видавництво ДУ «Львівська політехніка», 1999.— 25с.
J,H, Henness, D/A/ Patterson: Computer Architecture A Quantitative Approach. Morgan Kaufman Publishers, 1990.
Інтернет сайт фірми Aldec Inc.http://www.aldec.com/
Курс лекцій з дисципліни «Мови опису апаратних засобів».
Додаток
Gen_Defs
ibrary IEEE;
use IEEE.STD_LOGIC_1164.all;
package Gen_Defs is
-- Asynchronous level-sensetive memory type
type memory is array (0 to 127) of std_logic_vector(7 downto 0);
type REGFILE is array (0 to 15) of std_logic_vector(3 downto 0);
-- MCU Instruction Set
constant CLEAR_C : std_logic_vector(7 downto 0) := "00000000";
constant SET_C : std_logic_vector(7 downto 0) := "00000001";
constant SKIP_C : std_logic_vector(7 downto 0) := "00000010";
constant SKIP_Z : std_logic_vector(7 downto 0) := "00000011";
constant read_fifo: std_logic_vector(7 downto 0) := "00000111";
constant LOAD_IMM : std_logic_vector(3 downto 0) := "0001";
constant ADD_IMM : std_logic_vector(3 downto 0) := "0010";
constant STORE_DIR: std_logic_vector(3 downto 0) := "0011";
constant LOAD_DIR : std_logic_vector(3 downto 0) := "0100";
constant ADD_DIR : std_logic_vector(3 downto 0) := "0101";
constant XOR_DIR : std_logic_vector(3 downto 0) := "0110";
constant TEST_DIR : std_logic_vector(3 downto 0) := "0111";
constant JUMP : std_logic := '1';
-- ALU Operation Codes
constant NOP_OP : std_logic_vector(2 downto 0) := "000"; -- translate A
constant PASS_OP : std_logic_vector(2 downto 0) := "001"; -- translate B
constant ADD_OP : std_logic_vector(2 downto 0) := "010"; -- OUT = A + B + Ci; form C
constant XOR_OP : std_logic_vector(2 downto 0) := "011"; -- OUT = A ^ B
constant AND_OP : std_logic_vector(2 downto 0) := "100"; -- OUT = A & B; form Z
constant SET_CARRY_OP: std_logic_vector(2 downto 0) := "101"; -- C = 1
constant CLR_CARRY_OP: std_logic_vector(2 downto 0) := "110"; -- C = 0
end Gen_Defs;
SysMemory
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use WORK.GEN_DEFS.all;
entity SysMemory is
port(
ADDRESS: in std_logic_vector(6 downto 0);
nCSB : in std_logic;
nOEB : in std_logic;
DATA : out std_logic_vector(7 downto 0)
);
end SysMemory;
architecture Behavior of SysMemory is
begin
Read_Write:
process (ADDRESS, nCSB, nOEB)
variable mem_array: Memory := (others => "00000000");
-- variable sel : std_logic_vector(1 downto 0);
variable index : integer range 0 to 127;
begin
-- ROM program.
--- counter status
mem_array(5) := CLEAR_C; -- clear_c
mem_array(6) := READ_FIFO ; -- READ_FIFO
mem_array(7) := STORE_DIR & "0000"; -- store_dir r0 r0- counter
mem_array(8) := read_fifo ; -- READ_FIFO
mem_array(9) := STORE_DIR & "0001"; -- store_dir r1 r1- data register
mem_array(10) := LOAD_DIR & "0000"; -- load_dir r0
-- Memory behavior description
index := CONV_INTEGER(ADDRESS);
if nCSB = '1' then
DATA <= "ZZZZZZZZ";
else
if nOEB = '0' then
DATA <= mem_array(index);
else DATA <= "ZZZZZZZZ";
end if;
end if;
end process;
end Behavior;
---------------------------------------------------------------------------------------------------
regfiles
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use WORK.GEN_DEFS.all;
entity regfiles is
port(
ADDRESSR: in std_logic_vector(3 downto 0);
clk : in std_logic;
nWER : in std_logic;
ACCR : in std_logic_vector(3 downto 0);
DATAR : out std_logic_vector(3 downto 0)
);
end regfiles;
architecture Behavior of regfiles is
begin
Read_Write:
process (clk)
variable reg_array: REGFILE := (others => "0000");
variable index : integer range 0 to 15;
begin
if clk'Event and clk='1' then
if nWER = '1' then reg_array(CONV_INTEGER(ADDRESSR)) := ACCR; -- memory write
end if;
end if;
DATAR <= reg_array(index);
end process;
end Behavior;
ALU
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use WORK.GEN_DEFS.all;
entity ALU is
port(
CURR_ACC : in std_logic_vector(3 downto 0);
CURR_IR : in std_logic_vector(3 downto 0);
CURR_CARRY: in std_logic;
CURR_ZERO : in std_logic;
ALU_OP : in std_logic_vector(2 downto 0);
NEXT_ACC : out std_logic_vector(3 downto 0);
NEXT_CARRY: out std_logic;
NEXT_ZERO : out std_logic
);
end ALU;
architecture Behavior of ALU is
begin
PerformOperation:
process (CURR_ACC, CURR_IR, CURR_CARRY, CURR_ZERO, ALU_OP)
variable sm: std_logic_vector(4 downto 0);
begin
case ALU_OP is
when PASS_OP => NEXT_ACC <= CURR_IR;
NEXT_CARRY <= CURR_CARRY;
NEXT_ZERO <= CURR_ZERO;
when ADD_OP => sm := ('0' & CURR_ACC) + ('0' & CURR_IR) + ("0000" & CURR_CARRY);
NEXT_ACC <= sm(3 downto 0);
NEXT_CARRY <= sm(4);
if sm(3 downto 0) = "0000" then
NEXT_ZERO <= '1';
else
NEXT_ZERO <= '0';
end if;
when XOR_OP => NEXT_ACC <= CURR_ACC xor CURR_IR;
NEXT_CARRY <= CURR_CARRY;
NEXT_ZERO <= CURR_ZERO;
when AND_OP => NEXT_ACC <= CURR_ACC and CURR_IR;
NEXT_CARRY <= CURR_CARRY;
NEXT_ZERO <= not((CURR_ACC(3) and CURR_IR(3)) or
(CURR_ACC(2) and CURR_IR(2)) or
(CURR_ACC(1) and CURR_IR(1)) or
(CURR_ACC(0) and CURR_IR(0)));
when SET_CARRY_OP => NEXT_ACC <= CURR_ACC;
NEXT_CARRY <= '1';
NEXT_ZERO <= CURR_ZERO;
when CLR_CARRY_OP => NEXT_ACC <= CURR_ACC;
NEXT_CARRY <= '0';
NEXT_ZERO <= CURR_ZERO;
when others => NEXT_ACC <= CURR_ACC;
NEXT_CARRY <= CURR_CARRY;
NEXT_ZERO <= CURR_ZERO;
end case;
end process;
end Behavior;
Datapath
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Datapath is
port(
-- Control Unit Interface
CLK : in std_logic;
RESET : in std_logic;
WRITE : in std_logic;
READ : in std_logic;
JUMP_PC : in std_logic;
INC_PC : in std_logic;
LD_IR : in std_logic;
LD_IR_LSN : in std_logic;
ALU_OP : in std_logic_vector(2 downto 0);
IR_DATA : out std_logic_vector(7 downto 0);
Z_ST : out std_logic;
C_ST : out std_logic;
-- External Memory Interface
ADDRESS: out std_logic_vector(6 downto 0);
DATA : in std_logic_vector(7 downto 0);
nCSB : out std_logic;
-- nWEB : out std_logic;
nOEB : out std_logic;
-- from fifo
Qf : in std_logic_vector(3 downto 0);
full : in std_logic;
rdf : out std_logic;
rfifo : in std_logic;
rdfcu : in std_logic;
fullcu : out std_logic
);
end Datapath;
architecture Behavior of Datapath is
component ALU is
port(
CURR_ACC : in std_logic_vector(3 downto 0);
CURR_IR : in std_logic_vector(3 downto 0);
CURR_CARRY: in std_logic;
CURR_ZERO : in std_logic;
ALU_OP : in std_logic_vector(2 downto 0);
NEXT_ACC : out std_logic_vector(3 downto 0);
NEXT_CARRY: out std_logic;
NEXT_ZERO : out std_logic
);
end component ALU;
component regfiles is
port(
ADDRESSR: in std_logic_vector(3 downto 0);
clk : in std_logic;
nWER : in std_logic;
ACCR : in std_logic_vector(3 downto 0);
DATAR : out std_logic_vector(3 downto 0)
);
end component regfiles;
signal IR, NEXT_IR : std_logic_vector(7 downto 0); -- Instruction Register
signal ACC, NEXT_ACC: std_logic_vector(3 downto 0); -- ACCumulator
signal Z, NEXT_Z : std_logic; -- Z flag
signal C, NEXT_C : std_logic; -- C flag
signal PC, NEXT_PC : std_logic_vector(6 downto 0); -- Program Counter
signal ACCRNEXT, DATARNEXT, ADDRESSRNEXT : std_logic_vector(3 downto 0);
signal IRMUX : std_logic_vector(3 downto 0);
signal rdf_dp,full_dp : std_logic;
begin
-- Memory Control Signals
nCSB <= '0';
nOEB <= not READ;
-- Address Bus (Multiplexer M1)
ADDRESS <= PC;
-- Data to PC (Multiplexer M2 and SM)
NEXT_PC <= IR(6 downto 0) when JUMP_PC = '1' else PC + 1 when INC_PC = '1' else PC;
-- Data to IR
NEXT_IR <= DATA when LD_IR = '1' else (IR(7 downto 4) & DATARNEXT)
when LD_IR_LSN = '1' else IR;
--REG ADDRES
ADDRESSRNEXT <=IR(3 DOWNTO 0);
-- FROM ALU
IRMUX <= Qf when rfifo = '1' else IR(3 downto 0);
-- State signals to Control Unit
Z_ST <= Z;
C_ST <= C;
IR_DATA <= IR;
-- Datapath registers implementation
Registers:
process (CLK, RESET)
begin
if RESET = '1' then -- asynchronous reset
PC <= "0000000";
IR <= "00000000";
ACC <= "0000";
Z <= '0';
C <= '0';
elsif CLK'Event and CLK = '1' then
PC <= NEXT_PC;
IR <= NEXT_IR;
ACC <= NEXT_ACC;
Z <= NEXT_Z;
C <= NEXT_C;
end if;
end process;
rdf <= rdf_dp;
rdf_dp <= rdfcu;
fullcu <= full_dp;
full_dp <= full;
-- ALU connections
U0:
component ALU
port map(
CURR_ACC => ACC,
CURR_IR => IRMUX,
CURR_CARRY => C,
CURR_ZERO => Z,
ALU_OP => ALU_OP,
NEXT_ACC => NEXT_ACC,
NEXT_CARRY => NEXT_C,
NEXT_ZERO => NEXT_Z
);
U1:
component regfiles
port map(
ADDRESSR => ADDRESSRNEXT,
clk => CLK,
nWER => WRITE,
ACCR => NEXT_ACC,
DATAR => DATARNEXT
);
end Behavior;
-------
ControlUnit
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.GEN_DEFS.all;ControlUnit
entity ControlUnit is
port(
CLK : in std_logic;
RESET : in std_logic;
IR_DATA : in std_logic_vector(7 downto 0);
Z_ST : in std_logic;
C_ST : in std_logic;
WRITE : out std_logic;
READ : out std_logic;
JUMP_PC : out std_logic;
INC_PC : out std_logic;
LD_IR : out std_logic;
LD_IR_LSN : out std_logic;
ALU_OP : out std_logic_vector(2 downto 0);
-- fofo--
rdf : out std_logic;
rfifo : out std_logic;
full : in std_logic
);
end ControlUnit;
architecture Behavior of ControlUnit is
type MachineStates is (I_F, I_D, E_X);
signal STATE, NEXT_STATE: MachineStates;
begin
-- Control Unit is implemented as Mealy FSM
StateRegister:
process (CLK)
begin
if CLK'Event and CLK = '1' then
if RESET = '1' then
STATE <= I_F;
else
STATE <= NEXT_STATE;
end if;
end if;
end process;
Transition_and_Output_Function:
process (CLK)
begin
READ <= '0';
WRITE <= '0';
JUMP_PC <= '0';
INC_PC <= '0';
LD_IR <= '0'
LD_IR_LSN <= '0';
ALU_OP <= "000";
rfifo <= '0';
rdf <= '0';
case STATE is
when I_F => READ <= '1';
INC_PC <= '1';
LD_IR <= '1';
NEXT_STATE <= I_D;
when I_D => if IR_DATA(7 downto 4) = ADD_DIR or IR_DATA(7 downto 4) = XOR_DIR or
IR_DATA(7 downto 4) = LOAD_DIR or IR_DATA(7 downto 4) = TEST_DIR then
LD_IR_LSN <= '1';
end if;
NEXT_STATE <= E_X;
when E_X => if IR_DATA = CLEAR_C then
ALU_OP <= CLR_CARRY_OP;
end if;
if IR_DATA = SET_C then
ALU_OP <= SET_CARRY_OP;
end if;
if IR_DATA = SKIP_C then
if C_ST = '1' then
INC_PC <= '1';
end if;
end if;
if IR_DATA = SKIP_Z then
ALU_OP <= PASS_OP;
if Z_ST = '1' then
INC_PC <= '1';
end if;
end if;
if IR_DATA(7 downto 4) = LOAD_IMM or IR_DATA(7 downto 4) = LOAD_DIR then
ALU_OP <= PASS_OP;
end if;
if IR_DATA(7 downto 4) = ADD_IMM or IR_DATA(7 downto 4) = ADD_DIR then
ALU_OP <= ADD_OP;
end if;
if IR_DATA(7 downto 4) = STORE_DIR then
WRITE <= '1';
end if;
if IR_DATA(7 downto 4) = XOR_DIR then
ALU_OP <= XOR_OP;
end if;
if IR_DATA(7 downto 4) = TEST_DIR then
ALU_OP <= AND_OP;
end if;
if IR_DATA(7) = JUMP then
JUMP_PC <= '1';
ALU_OP <= PASS_OP;
end if;
if IR_DATA(7 downto 0) = read_fifo then
rfifo <= '1';
rdf <= '1';
ALU_OP <= PASS_OP;
end if;
NEXT_STATE <= I_F;
end case;
end process;
end Behavior;
GnomeMCU
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity GnomeMCU is
port(
CLOCK: in std_logic;
RESET: in std_logic;
-- Memory interface
ADDRESS: out std_logic_vector(6 downto 0);
DATA : in std_logic_vector(7 downto 0);
Qf : in std_logic_vector(3 downto 0); --add
nCSB : out std_logic;
nOEB : out std_logic;
fullf : in std_logic; --add
rdf : out std_logic --add
);
end GnomeMCU;
architecture Structure of GnomeMCU is
component ControlUnit is
port(
CLK : in std_logic;
RESET : in std_logic;
IR_DATA : in std_logic_vector(7 downto 0);
Z_ST : in std_logic;
C_ST : in std_logic;
WRITE : out std_logic;
READ : out std_logic;
JUMP_PC : out std_logic;
INC_PC : out std_logic;
LD_IR : out std_logic;
LD_IR_LSN : out std_logic;
ALU_OP : out std_logic_vector(2 downto 0);
-- add potr
-- fofo--
rdf : out std_logic;
rfifo : out std_logic;
full : in std_logic
);
end component ControlUnit;
component Datapath is
port(
-- Control Unit Interface
CLK : in std_logic;
RESET : in std_logic;
WRITE : in std_logic;
READ : in std_logic;
JUMP_PC : in std_logic;
INC_PC : in std_logic;
LD_IR : in std_logic;
LD_IR_LSN : in std_logic;
ALU_OP : in std_logic_vector(2 downto 0);
IR_DATA : out std_logic_vector(7 downto 0);
Z_ST : out std_logic;
C_ST : out std_logic;
-- External Memory Interface
ADDRESS: out std_logic_vector(6 downto 0);
DATA : in std_logic_vector(7 downto 0);
nCSB : out std_logic;
nOEB : out std_logic;
Qf : in std_logic_vector(3 downto 0);
full : in std_logic;
rdf : out std_logic;
rfifo : in std_logic;
rdfcu : in std_logic;
fullcu : out std_logic
);
end component Datapath;
signal IR_DATA_BUS: std_logic_vector(7 downto 0);
signal Z_ST_NET, C_ST_NET, WRITE_NET, READ_NET, JUMP_PC_NET, INC_PC_NET,
LD_IR_NET, LD_IR_LSN_NET: std_logic;
signal ALU_OP_BUS : std_logic_vector(2 downto 0);
signal fullfnet, rdfnet, clkfnet : std_logic;-- gnom
signal Qfnet : std_logic_vector(3 downto 0); -- gnom
signal rdfcunet,rfifocunet,fullcunet: std_logic; --cu
begin
U0: component Datapath
port map(
-- External memory interface
ADDRESS => ADDRESS,
DATA => DATA,
nCSB => nCSB,
nOEB => nOEB,
-- Control unit connections
CLK => CLOCK,
RESET => RESET,
WRITE => WRITE_NET,
READ => READ_NET,
JUMP_PC => JUMP_PC_NET,
INC_PC => INC_PC_NET,
LD_IR => LD_IR_NET,
LD_IR_LSN => LD_IR_LSN_NET,
ALU_OP => ALU_OP_BUS,
IR_DATA => IR_DATA_BUS,
Z_ST => Z_ST_NET,
C_ST => C_ST_NET,
Qf => Qf,
full => fullf,
rdf => rdf,
rfifo => rfifocunet,
rdfcu => rdfcunet,
fullcu => fullcunet
);
U1: component ControlUnit
port map(
CLK => CLOCK,
RESET => RESET,
-- Datapath connections
IR_DATA => IR_DATA_BUS,
Z_ST => Z_ST_NET,
C_ST => C_ST_NET,
WRITE => WRITE_NET,
READ => READ_NET,
JUMP_PC => JUMP_PC_NET,
INC_PC => INC_PC_NET,
LD_IR => LD_IR_NET,
LD_IR_LSN => LD_IR_LSN_NET,
ALU_OP => ALU_OP_BUS,
rdf => rdfcunet,
rfifo => rfifocunet,
full => fullcunet
);
end Structure;
Computer
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Computer is
port(
CLOCK: in std_logic;
RESET: in std_logic;
DATAF: in std_logic_vector(3 downto 0);
WRF : in std_logic;
clr : in std_logic
);
end Computer;
architecture TopLevel of Computer is
component GnomeMCU is
port(
CLOCK: in std_logic;
RESET: in std_logic;
-- Memory interface
ADDRESS: out std_logic_vector(6 downto 0);
DATA : in std_logic_vector(7 downto 0);
nCSB : out std_logic;
-- nWEB : out std_logic;
nOEB : out std_logic;
-- fifo--
Qf : in std_logic_vector(3 downto 0);
fullf : in std_logic;
rdf : out std_logic
);
end component GnomeMCU;
component SysMemory is
port(
ADDRESS: in std_logic_vector(6 downto 0);
nCSB : in std_logic;
nOEB : in std_logic;
DATA : out std_logic_vector(7 downto 0)
);
end component SysMemory;
component fifo1 is
port(
CLR : in std_logic;
CLK : in std_logic;
RD : in std_logic;
WR : in std_logic;
DATAff : in std_logic_vector (3 downto 0);
FULL : out std_logic;
Q : out std_logic_vector (3 downto 0)
);
end component;
signal DATA_BUS : std_logic_vector(7 downto 0);
signal ADDRESS_BUS : std_logic_vector(6 downto 0);
signal nCSB_NET, nOEB_NET, nWEB_NET: std_logic;
signal clrf_net, full_net, rdf_net : std_logic;
signal Q_bus : std_logic_vector(3 downto 0);
begin
CPU: component GnomeMCU
port map(
CLOCK => CLOCK,
RESET => RESET,
ADDRESS => ADDRESS_BUS,
DATA => DATA_BUS,
nCSB => nCSB_NET,
nOEB => nOEB_NET,
-- add fifo--
Qf => Q_bus,
fullf => full_net,
rdf => rdf_net
);
SYSMEM: component SysMemory
port map(
ADDRESS => ADDRESS_BUS,
DATA => DATA_BUS,
nCSB => nCSB_NET,
nOEB => nOEB_NET
);
FIFO_labe: component fifo1
port map (
Q => Q_bus,
full => full_net,
rd => rdf_net,
clk => CLOCK,
clr => clr,
WR => WRF,
DATAff => DATAF
);
end TopLevel;