Код операции
|
Команды
|
0
|
0
|
Jmp #
|
0
|
1
|
Mov A,#
|
1
|
0
|
Mov Rn,#
|
1
|
1
|
Rl A
|
Временная
диаграмма микроопераций выполнения команды JMP #d:
Временная
диаграмма микроопераций выполнения команды MOV A, #d:
Временная
диаграмма микроопераций выполнения команды MOV Rn, #d:
Временная
диаграмма микроопераций выполнения команды RL A:
4
СОДЕРЖАТЕЛЬНЫЙ АЛГОРИТМ МИКРОПРОГРАММЫ
Опишем
основные алгоритмы выполнения команд в процессоре по тактам с краткими
пояснениями к каждой из них:
Переход
в заданную часть кода (JMP #d)
1
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
2
MBROut, IRIn
(загрузка из MBR, загрузка следующей команды)
3
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
4
MBROut, PCIn
(загрузка из MBR)
5
Reset (сброс)
Загрузка
константы в аккумулятор (MOV A, #d)
1
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
2
MBROut, IRIn
(загрузка из MBR, загрузка следующей команды)
3
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
4
MBROut, AccIn,
Reset (загрузка из MBR, загрузка в аккумулятор, сброс)
Загрузка
константы в РОН (MOV Rn, #d)
1
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
2
MBROut, IRIn
(загрузка из MBR, загрузка следующей команды)
3
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
4
MBROut, RegIn,
Reset (загрузка из MBR, загрузка в РОН, сброс)
Сдвиг
аккумулятора влево циклический (RL A)
1
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
2
MBROut, IRIn
(загрузка из MBR, загрузка следующей команды)
3
MemRd, PCInc
(чтение из памяти, инкремент программного счетчика)
4
MBROut (загрузка
из MBR)
5
ALUOP, AccIn,
Reset (выполнение операции, загрузка результата в аккумулятор, сброс)
5 СИНТЕЗ УПРАВЛЯЮЩЕГО
АВТОМАТА НА ОСНОВЕ ЖЕСТКОЙ ЛОГИКИ
Структурная
схема управляющего автомата на основе жесткой логики показана на рис. 2.
Рис.
2. Структурная схема управляющего автомата на основе жесткой логики
Ниже
записаны выражения для выходных сигналов шифратора:
MemRd<='1' when c="00000001" or c="00000100" else
'0' after 5ns;
PCInc<='1' when c="00000001" or c="00000100" else
'0' after 5ns;
MBROut<='1' when c="00000010" or c="00001000" else
'0' after 5ns;
IrIn<='1' when c="00000010" else '0' after 5ns;
PCIn<='1' when c="00001000" and i="0001" else '0'
after 5ns;
AccIn<='1' when (c="00001000" and i="0010") or
(c="00010000" and i="1000") else '0' after 5ns;
RegIn<='1' when c="00001000" and i="0100" else '0'
after 5ns;
ALURL<='1' when c="00010000" and i="1000" else '0'
after 5ns;
Reset<='1' when (c="00010000" and i="0001") or
(c="00010000" and i="1000")
or (c="00001000" and i="0010")or
(c="00001000" and i="0100") else '0' after 5ns;
6 СОЗДАНИЕ ОПИСАНИЯ
ОТДЕЛЬНЫХ УЗЛОВ ПРОЦЕССОРА И ВСЕГО ПРОЦЕССОРА СРЕДСТВАМИ ACTIVE HDL
Описание
регистров, счетчика, мультиплексора и декодера:
library ieee;
use ieee.std_logic_1164.all;
entity MAR is
port(D: in std_logic_vector(7 downto 0);
Q: out std_logic_vector(7 downto 0);
RST: in std_logic;
Clk: in std_logic);
end MAR;
architecture MAR of MAR is
signal master, slave: std_logic_vector(7 downto 0);
begin
Q<=slave;
process(D,RST,Clk)
begin
if Clk='0' then
if RST='1'then master<=(others => '0')
after 2ns;
else master<=D
after 2ns;
end if;
end if;
end process;
process(master,Clk)
begin
if Clk='1'then slave<=master after 2ns;
end if;
end process;
end architecture MAR;
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity REGI is
port(D: in std_logic_vector(7 downto 0);
Q: out std_logic_vector(7 downto 0);
EI: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end REGI;
architecture REGI of REGI is
signal master, slave: std_logic_vector(7 downto 0);
begin
Q<=slave;
process(D,RST,Clk,EI)
begin
if Clk='0'then
if RST='1' then master<=(others => '0')
after 2ns;
elsif EI='1' then
master<=D after 2ns;
end if;
end if;
end process;
process(master,Clk)
begin
if Clk='1'then slave<=master after 2ns;
end if;
end process;
end architecture REGI;
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity MBR is
port(D: in std_logic_vector(7 downto 0);
Q: out std_logic_vector(7 downto 0);
EO: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end MBR;
architecture MBR of MBR is
signal master, slave: std_logic_vector(7 downto 0);
begin
process(D,RST,Clk)
begin
if Clk='0'then
if RST='1' then master<=(others => '0')
after 2ns;
else master<=D
after 2ns;
end if;
end if;
end process;
process(master,Clk)
begin
if Clk='1'then slave<=master after 2ns;
end if;
end process;
process(slave,EO)
begin
if EO='1'then Q<=slave;
else Q<=(others => 'Z');
end if;
end process;
end architecture MBR;
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Counter is
port(Q: out std_logic_vector(2 downto 0);
RST: in std_logic;
Clk: in std_logic);
end Counter;
architecture Counter of Counter is
signal master, slave, slave_inc: std_logic_vector(2 downto 0);
begin
Q<=slave;
slave_inc<=slave+1 after 2ns;
process(slave_inc,RST,Clk)
begin
if Clk='0'then
if RST='1'then master<=(others => '0')
after 2ns;
else master<=slave_inc
after 2ns;
end if;
end if;
end process;
process(master,Clk)
begin
if Clk='1' then slave<=master after 2ns;
end if;
end process;
end Counter;
----------------------------------------------------------------------------------
library 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);
Q: out std_logic_vector(7 downto 0);
EI: in std_logic;
Inc: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end PC;
architecture PC of PC is
signal master, slave, slave_inc: std_logic_vector(7 downto 0);
begin
Q<=slave;
slave_inc<=slave+1 after 2ns;
process(D,RST,Clk,EI,Inc,slave_inc)
begin
if Clk='0' then
if RST='1' then master<=(others => '0')
after 2ns;
elsif EI='1'
then master<=D after 2ns;
elsif Inc='1'
then master<=slave_inc after 2ns;
end if;
end if;
end process;
process(master,Clk)
begin
if Clk='1'then slave<=master after 2ns;
end if;
end process;
end PC;
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Decoder is
generic(n: integer:=2);
port(D: in std_logic_vector(n-1 downto 0);
Q: out std_logic_vector((2**n)-1 downto 0));
end Decoder;
architecture Decoder of Decoder is
begin
process(D)
variable i:integer;
variable s:bit_vector((2**n)-1 downto 0);
begin
s:=(0 => '1', others => '0');
i:=conv_integer(D);
s:=s rol i;
for ind in 2**n-1 downto 0 loop
if s(ind)='0' then Q(ind)<='0' after 2ns;
else Q(ind)<='1' after 2ns;
end if;
end loop;
end process;
end architecture;
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity MUX is
port(D: in std_logic_vector(1 downto 0);
P: in std_logic;
Q: out std_logic_vector(3 downto 0));
end
MUX;
architecture MUX of MUX is
begin
process(D,P)
variable i:integer;
variable s:bit_vector(3 downto 0);
begin
s:=(0 => '1', others => '0');
i:=conv_integer(D);
s:=s rol i;
for ind in 3 downto 0 loop
if s(ind)='0' then Q(ind)<='0' after 2ns;
else Q(ind)<=P after 2ns;
end if;
end loop;
end process;
end architecture MUX;
----------------------------------------------------------------------------------
Описание блока РОН:
library ieee;
use ieee.std_logic_1164.all;
entity BlockRG is
port(D: in std_logic_vector(7 downto 0);
Addr: in std_logic_vector(1 downto 0);
EI: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end BlockRG;
architecture BlockRG of BlockRG is
signal Enable: std_logic_vector(3 downto 0);
component REGI is
port(D: in std_logic_vector(7 downto 0);
Q: out std_logic_vector(7 downto 0);
EI: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end component REGI;
component MUX is
P: in std_logic;
Q: out std_logic_vector(3 downto 0));
end component MUX;
begin
Registers: for i in 3 downto 0 generate
Reg: REGI port
map(D=>D,Q=>open,EI=>Enable(i),RST=>RST,Clk=>Clk);
end generate;
Switch: MUX port map(D=>Addr,P=>EI,Q=>Enable);
end
BlockRG;
Описание
узла АЛУ:
library
ieee;
use ieee.std_logic_1164.all;
entity ALU is
port(In1: in std_logic_vector(7 downto 0);
OP: in std_logic;
Res: out std_logic_vector(7 downto 0);
RST: in std_logic;
Clk: in std_logic);
end ALU;
architecture ALU of ALU is
signal RL :std_logic_vector(7 downto 0);
component MBR is
port(D: in std_logic_vector(7 downto 0);
Q: out std_logic_vector(7 downto 0);
EO: in std_logic;
RST: in std_logic;
Clk: in std_logic);
end component;
begin
DD0:for i in 7 downto 1 generate
RL(i)<=In1(i-1);
end generate;
RL(0) <= In1(7) after 10ns;
BUFF: MBR port map(D=>RL,Q=>Res,EO=>OP,RST=>RST,Clk=>Clk);
end
architecture;
Временная
диаграмма АЛУ:
Как
видно из диаграммы общая задержка на этом узле 14,5 ns.
Описание
узла памяти Memory:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity Memory is
generic(file_name: string:= "MEM.DAT");
port (addr: in std_logic_vector(7 downto 0);
data: out std_logic_vector(7 downto 0);
rd: in std_logic;
ld: in std_logic);
end Memory;
architecture Memory of Memory is
type t_rom_data is array (15 downto 0) of std_logic_vector(7 downto 0);
type rom_file_type is file of character;
file rom_file: rom_file_type;
signal rom_data: t_rom_data;
begin
process(addr,rd)
variable i: natural;
begin
if rd = '1' then
i := conv_integer(addr);
data <= rom_data(i) after 5ns;
else
data <= (others => 'Z');
end if;
end process;
process(ld)
variable c: character;
begin
if ld='1' then file_open(rom_file,file_name,read_mode);
for i in 0 to 15 loop
for b in 7 downto 0 loop
c:='U';
if not(endfile(rom_file))
then read(rom_file,c);
while not(endfile(rom_file))
and c/='0' and c/='1' and c/='Z' and c/='W'
and c/='L' and
c/='H' and c/='-' and c/='X' and c/='U' loop
read(rom_file,c);
end loop;
end if;
if c='0' then
rom_data(i)(b) <= '0';
elsif c='1' then rom_data(i)(b)
<='1';
elsif c='Z' then
rom_data(i)(b) <='Z';
elsif c='W' then
rom_data(i)(b) <='W';
elsif c='L' then
rom_data(i)(b) <='L';
elsif c='H' then
rom_data(i)(b) <='H';
elsif c='-' then
rom_data(i)(b) <='-';
elsif c='X' then rom_data(i)(b)
<='X';
else rom_data(i)(b)
<='U';
end if;
end loop;
end loop;
file_close(rom_file);
end if;
end process;
end Memory;
Временная
диаграмма работы памяти:
Описание
блока управления:
library ieee;
use ieee.std_logic_1164.all;
entity CU is
port(Instr: in std_logic_vector(1 downto 0);
AccIn: out std_logic;
ALURL: out std_logic;
RegIn: out std_logic;
PCIn: out std_logic;
PCInc: out std_logic;
MBROut: out std_logic;
IRIn: out std_logic;
MEMRd: out std_logic;
Reset: inout std_logic;
RST: in std_logic;
Clk: in std_logic);
end CU;
architecture CU of CU is
signal R: std_logic;
signal InstrDecoded,i: std_logic_vector(3 downto 0);
signal CounterPacked: std_logic_vector(2 downto 0);
signal CounterDecoded,c: std_logic_vector(7 downto 0);
component Counter is
port(Q: out std_logic_vector(2 downto 0);
RST: in std_logic;
Clk: in std_logic);
end component;
component Decoder is
generic(n: integer:=2);
port(D: in std_logic_vector(n-1 downto 0);
Q: out std_logic_vector((2**n)-1 downto 0));
end component;
begin
DD0: Counter port map(Q=>CounterPacked,RST=>R,Clk=>Clk);
InstrDecoder: Decoder generic map(2)port
map(D=>Instr,Q=>InstrDecoded);
CounterDecoder: Decoder generic map(3)port
map(D=>CounterPacked,Q=>CounterDecoded);
c<=CounterDecoded;
i<=InstrDecoded;
MemRd<='1' when c="00000001" or c="00000100" else
'0' after 5ns;
PCInc<='1' when c="00000001" or c="00000100" else
'0' after 5ns;
MBROut<='1' when c="00000010" or c="00001000" else
'0' after 5ns;
IrIn<='1' when c="00000010" else '0' after 5ns;
PCIn<='1' when c="00001000" and i="0001" else '0'
after 5ns;
AccIn<='1' when (c="00001000" and i="0010") or
(c="00010000" and i="1000") else '0' after 5ns;
RegIn<='1' when c="00001000" and i="0100" else '0'
after 5ns;
ALURL<='1' when c="00010000" and i="1000" else '0'
after 5ns;
Reset<='1' when (c="00010000" and i="0001") or
(c="00010000" and i="1000")
or (c="00001000" and i="0010")or
(c="00001000" and i="0100") else '0' after 5ns;
R<=RST
or Reset;
end
architecture;
7 ТЕСТИРОВАНИЕ
ПРОЦЕССОРА И ПОДТВЕРЖДЕНИЕ ПРАВИЛЬНОСТИ ЕГО РАБОТЫ С ПОМОЩЬЮ ВРЕМЕННЫХ ДИАГРАММ
Описание
процессора:
library ieee;
use ieee.std_logic_1164.all;
entity CPU is
generic(file_name: string:=".\src\MEM.DAT");
port(RST: in std_logic;
Clk: in std_logic);
end entity;
architecture CPU of CPU is
-----------------------------------------------------------
component MAR is
port(D: in
std_logic_vector(7 downto 0);
Q: out
std_logic_vector(7 downto 0);
RST: in
std_logic;
Clk: in
std_logic);
end component;
-----------------------------------------------------------
component REGI is
port(D: in
std_logic_vector(7 downto 0);
Q: out
std_logic_vector(7 downto 0);
EI: in std_logic;
RST: in
std_logic;
Clk: in
std_logic);
end component;
------------------------------------------------------------
component MBR is
port(D: in
std_logic_vector(7 downto 0);
Q: out
std_logic_vector(7 downto 0);
EO: in std_logic;
RST: in
std_logic;
Clk: in std_logic);
end component;
-------------------------------------------------------------
component PC is
port(D: in
std_logic_vector(7 downto 0);
Q: out
std_logic_vector(7 downto 0);
EI: in std_logic;
Inc: in
std_logic;
RST: in
std_logic;
Clk: in
std_logic);
end component;
--------------------------------------------------------------
component
ALU is
port(In1: in
std_logic_vector(7 downto 0);
OP: in std_logic;
Res: out
std_logic_vector(7 downto 0);
RST: in std_logic;
Clk: in std_logic);
end component;
---------------------------------------------------------------
component BlockRG is
port(D: in
std_logic_vector(7 downto 0);
Addr: in
std_logic_vector(1 downto 0);
EI: in std_logic;
RST: in std_logic;
Clk: in
std_logic);
end component;
----------------------------------------------------------------
component Memory is
generic(file_name: string:=
"MEM.DAT");
port (addr: in
std_logic_vector(7 downto 0);
data: out
std_logic_vector(7 downto 0);
rd: in std_logic;
ld: in
std_logic);
end component;
-----------------------------------------------------------------
component
CU is
port(Instr: in
std_logic_vector(1 downto 0);
AccIn: out
std_logic;
ALURL: out
std_logic;
RegIn: out
std_logic;
PCIn: out
std_logic;
PCInc: out std_logic;
MBROut: out std_logic;
IRIn: out
std_logic;
MEMRd: out
std_logic;
Reset: inout
std_logic;
RST: in std_logic;
Clk: in std_logic);
end component;
signal AccIn,ALURL,RegIn,PCIn,PCInc,MBROut,IRIn,MEMRd,Reset:std_logic;
signal Inst_Addr:std_logic_vector(7 downto 0);
signal mem_mbr,BUS1,pc_mar,mar_mem,acc_alu:std_logic_vector(7
downto 0);
begin
DD0: CU port map(Instr=> Inst_Addr(7 downto 6),AccIn=>
AccIn,ALURL=> ALURL,
RegIn=> RegIn,PCIn=> PCIn,PCInc=>
PCInc,MBROut=> MBROut,IRIn=> IRIn,
MEMRd=> MEMRd,Reset =>Reset,RST =>
RST, Clk => Clk);
DD1: ALU port map(In1=> acc_alu,OP=> ALURL,Res=> BUS1,RST=>
RST,Clk => Clk);
DD2: Memory generic map(file_name)port map(addr => mar_mem,data =>
mem_mbr,rd=> MEMRd,ld=> RST);
DD3: BlockRG port map(D => BUS1,Addr=> Inst_Addr(5 downto 4),EI =>
RegIn,RST=> RST,Clk=> Clk);
IR: REGI port map(D => BUS1,Q=> Inst_Addr,EI=> IRIn,RST =>
RST, Clk => Clk);
DD4: MBR port map(D=> mem_mbr,Q=> BUS1,EO=> MBROut,RST =>
RST, Clk => Clk);
DD5: MAR port map(D => pc_mar,Q => mar_mem,RST =>
RST, Clk => Clk);
DD6: PC port map(D=> BUS1,Q => pc_mar,EI=> PCIn,Inc =>
PCInc,RST=> RST,Clk=> Clk);
ACC: REGI port map(D=> BUS1,Q=> acc_alu,EI=> AccIn,RST=>
RST,Clk=> Clk);
end
CPU;
Программа
для проверки работоспособности процессора написана в отдельном файле Mem.dat, хранящемся на диске, и подгружается в память прямо в
процессе работы средствами языка VHDL. Приведем пример тестовой программы и
покажем результаты ее работы.
01.00.0000 11111111 ;mov
a,#
10.00.0000 00000001 ;mov ro,#
10.01.0000 00000010 ;mov rl,#
10.10.0000 00000100 ;mov r2,#
10.11.0000 00001000 ;mov r3,#
01.00.0000 00000001 ;mov a,#
11.00.0000 00000000 ;rl a
00.00.0000 00001100 ;jmp
#
Обработчик
файла построен таким образом, что игнорируются все символы, не входящие в тип
std_logic. Первый столбец, первые 2 бита – код команды, вторые 2 бита - номер
РОН), второй столбец – операнды. В случае с командой сдвига содержимое поля
операнда не имеет значения.
Загружается
число в аккумулятор, затем в каждый из РОН, после чего производится очередная
запись в аккумулятор и сдвиг его содержимого, искусственно зацикленный
командой JMP.
Временная
диаграмма работы процессора при заданной программе приведена на рис. 3, где data – данные из памяти. На рис. 4. можно
увидеть задержки и определить временные характеристики работы процессора.
Рис.
3. Временная диаграмма работы процессора
Рис.
4. Временная диаграмма работы процессора
ВЫВОДЫ
При
выполнении курсовой работы было произведено моделирование процессора с
устройством управления на жёсткой логике, имеющего ряд специальных регистров, а
также четыре регистра общего назначения. Тестовая программа была успешно
выполнена, что вполне свидетельствует о его корректной работе.
Структурная
схема, разработанная в этой работе, естественно, не является единственно
возможной. Но на ее примере можно усвоить основные принципы построения цифровых
вычислительных систем, такие как микропрограммное управление, совместное
использование шин процессора различными устройствами со всеми вытекающими
отсюда требованиями к организации работы этих устройств: синхронизации,
сингулярности передач информации и другими.
Данная
схема обладает одной магистралью, она достаточно проста в исполнении, хотя
одномагистральная система не всегда позволяет просто реализовать некоторые
операции, а именно такая система занимает намного меньше места на печатной
плате чем двухмагистральная (и тем более трехмагистральная), что и дает ей
преимущества при конструировании небольших устройств.
По
диаграмме работы процессора видно, что выполнение команды пересылки занимает в
среднем 100 ns, команда сдвига немного больше 125 ns. Полное выполнение всех команд
производится за 1050 ns.