Міністерство освіти і науки України
Національний університет „Львівська політехніка”
Кафедра СКС
Курсова робота
з курсу: “Дослідження та проектування СКС”
на тему: „РОЗРОБКА VHDL МОДЕЛІ КОМП’ЮТЕРА”
Львів-2009
Зміст
1. Вихідні дані на проектування і їхній аналіз ..............................................3
2. Внутрішня структура байту ........................................................................4
3. Розробка архітектури рівня машинних інструкцій ...................................5
4. Програмна модель комп’ютера ...................................................................8
5. Розробка VHDL моделі тестової програми ................................................9
6. Розробка VHDL моделі процесора..............................................................10
7. Розробка VHDL моделі пам’яті даних…....................................................20
8. Розробка VHDL моделі пам’яті програм....................................................25
9. Розробка VHDL моделі комп’ютера...........................................................29
--10. Розробка VHDL моделі додаткового апаратного блоку ……………….35
Література....................................................................................................33
1. Вихідні дані на проектування
Скласти, імлементувати і верифікувати VHDL модель чотирибітового вбудованого до ПЛІС (софт) комп’ютера, що містить процесор, пам'ять даних і машинних кодів. Цільові ПЛІС – від фірми Ксайлінкс, родини Віртекс або Спартан. САПР розробки – Ксайлінкс WebPack, симулятор – ModeSim Model Тechnologies .
За основу архітектури чотирибітового процессора рівня машинних інструкцій прийняти архітектуру процесора Gnome [1, стор. 253], а за основу прототипної плати прийняти прототипну плату XS40 [1, стор. 325]. Розробити принципову схему відповідного проекту апаратного емулятора (прототипної плати).
Провести модифікацію готової моделі мікрокомп’ютера згідно до власного варіанту: Варіант № 14.
2. Внутрішня структура байту
Маємо комп’ютер з чотири бітовими даними і байтовими інструкціями. Сусідні чотири біти формтату, що утворюють єдине поле певного призначення називають ніблом (nibble, тетрада). Один байт містить дві тетради:
найбільш значний нібл (MSN, в нас - розташований ліворуч);
найменш значний нібл (LSN, в нас – розташований праворуч).
Приймаємо, що нумерація бітів в байті відбувається зправа наліво. При цьому найбільш значним є лівий сьомий біт, а найменш значним – правий нульовий біт.
3. Розробка архітектури рівня машинних інструкцій
Інформацію про інструкції, що виконує процесор “Гном” подамо наступними двома таблицями.
Таблиця 1 – Перелік і функції машинних інструкцій процесора “Гном”
Система інструкцій належить до класу RISC:
набір інструкцій скорочений до мінімуму;
інструкції мають код операції однакової довжини;
інструкції приведені до одного стандартного для всієї їх множини виду.
Таблиця 2 – Кодування і виконання в часі машинних інструкцій
IR –регістр інструкції, а [IR..IR0] – бінарний код, що зберігає його молодший нібл.
([IR3..IR0]) – вмістиме комірки пам’яты даних за адресою, що містить молодший нібл регістра інструкцій.
Виконання будь-якої інструкції розкладено на три часові інтервали:
FETCH, вибирання нової інструкції з пам’яті інструкцій на регістр інструкцій, обчислення адреси наступної інструкції програми за лінійним правилом “поточна адреса + !”;
DECODE, декодування тепер вже поточної інструкції (в нас – це читання операнду зпам’яті даних до молодшого ніблу регістру інструкцій;
EXECUTE, виконання поточної інструкції за її алгоритмом, що може навіть вимагати кореції вмістимого програмного лічильника РС.
d3, d2, d1, d0, a6, a5, a4, a3, a2, a1, a0 – це окремі біти з формату машинної інструкції.
Зазначимо, що процесор не є конвеєрним. Отже, доки виконуються всі три стадії поточної інструкції, обробка наступної інструкції не розпочинається. При цьому відсутні відомі негативні ефекти конвеєрного опрацювання непаралельного потоку інструкцій, а саме, виникнення і необхідність скасування залежностей даних, керування і структур.
Отже, тут маємо неконвеєрне (простіше) трициклове виконання кожної машинної інструкції.
Для конвеєризації даної системи інструкцій, що виконують вибірку, декодування і виконання необхідно поставити конвеєрні регістри.
У відповідності з особистим варіантом були додані наступні інструкції:
4. Програмна модель комп’ютера
Програмна модель комп’ютера відповідає уявленню системного програміста про наш комп’ютер. Це уявлення можна проілюструвати наступним рисунком.
Комп’ютер містить наступні найважливіші програмно керовані вузли:
Програмну (може бути відокремленою і постійною) пам’ять для 128 байтових інструкцій. Пам’ять містить байтові комірки з адресами від 0х00 до 0хFF.
Пам’ять даних (може бути відокремленою від пам’яті програм) з довільним доступом (RAM/ПДД). Пам’ять містить ніблові комірки з адресами від 0х0 до 0хF.
Арифметичний і логічний пристрій (може бути комбінаційним) (ALU/АЛП).
Регістр, що нагромаджує результат (акумулятор, АК/ACC).
Однобітові означні прапорці нульового результату і переносу (Zero, Carry).
5. Розробка тестової програми
Призначення тестової програми – це остаточно верифікувати розроблений і імплементований комп’ютер.
Маючи тестову програму це можна зробити двома варіантами.
Виконати часове моделювання функціонування комп’ютера, що керується певною тестовою програмою (віртуальна верифікація).
Завантажити отриманий за допомогою САПР, засобами якої ми розробляли проект, бінарний файл конфігурації до ПЛІС емулятора/прототипної плати, тобто, до друкованого вузла, що містить цільову ПЛІС і допоміжні елементи, і (можливо, за допомогою осцилографа) переконатися , що поведінка комп’ютера повністю визначена тестовою програмою (реальна верифікація).
Обидва способи не гарантують виявлення усіх можливих помилок в результатах проектування. Проте імовірність існування цих помилок вони зменшують. А все це спричинене неможливістю формального математичного доведення коректності функціонування машини з програмою, що зберігається в пам’яті, під дією всіх варіантів прорамі їхніх даних.
Ми розробили тестову програму для ніблової (чотирибітової) машини, що додає дворозрядні 16-кові (гексадецимальні) числа, виконуючи водночас операції лише з одною (а не з двома, як зручно) цифрами цих чисел.
Таблиця 3 – Асемблерна тестова програма і її машинні коди
Машинні коди тестової програми мають міститися в VHDL моделі пам’яті програм. Інакше ми не зможемо визначити цю модель. Для пар інструкцій, позначені червоним, а саме 0х53/0x35 і 0x44/0x8F методом часового симулювання вироблено і проаналізовано часові діаграми виконання.
6. Розробка VHDL моделі процесора
Виконаємо розробку VHDL моделі процесора на основі прототипної моделі процесора “Gnome”, що подана роботою [1], але мовою ABEL. На відміну від прототипа, що є орієнтованим на імплементування до конкретної прототипної плати (ПЛІС серії 4000, зовнішня щодо ПЛІС мікросхема статичної памэ’ті з байтовою організацією), ми маємо цільовою ПЛІС проекту Віртекс-2 з вбудованими елементами RAM, ROM. При цьому з двох варіантів складання системи з CPU, RAM, ROM) ми обрали варіант вбудованої до ПЛІС тристабільної системної шини. В іншому варіанті тристабільну шину можна не використовувати. Далі подамо текст моделі.
LIBRARY IEEE;
LIBRARY a40mx;
Use a40mx.all;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
-- Опис інтерфейсу Гном
ENTITY gnome IS
PORT (
clk: IN STD_LOGIC; -- сигнал синхронізації
reset: IN STD_LOGIC; -- сигнал скиду
address: OUT STD_LOGIC_VECTOR (6 DOWNTO 0); - лінії адрес зовнішньої RAM
data: INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); -- шина даних
ext_bus: INOUT STD_LOGIC_VECTOR (3 DOWNTO 0);
web: OUT STD_LOGIC; -- не дозвіл запису RAM
oeb: OUT STD_LOGIC; -- не дозвіл RAM
sel_ram: out std_logic;
carry_out : out std_logic;
pc_out: OUT STD_LOGIC_VECTOR (6 DOWNTO 0);
ir_out: out std_logic_vector (7 downto 0);
io_r: OUT STD_LOGIC; -- external RAM active-low write-enable
io_w: OUT STD_LOGIC;
acc_out: out std_logic_vector (3 downto 0)
);
END gnome;
-- архітектура GNOME
ARCHITECTURE gnome_arch OF gnome IS
-- сигнали стану автомата керування
SIGNAL curr_st, next_st: STD_LOGIC_VECTOR (1 DOWNTO 0);
-- етапи виконання команди
CONSTANT FETCH: STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"; -- fetch instruction
CONSTANT DECODE: STD_LOGIC_VECTOR (1 DOWNTO 0) := "01"; -- decode
CONSTANT EXECUTE: STD_LOGIC_VECTOR (1 DOWNTO 0) := "11"; -- execute
-- біжуча і наступна значення лічильника команд
SIGNAL curr_pc, next_pc: STD_LOGIC_VECTOR (6 DOWNTO 0);
-- біжуче і наступне значення акумулятора
SIGNAL curr_acc, next_acc: STD_LOGIC_VECTOR (3 DOWNTO 0);
-- біжуче і наступне значення ознаки переносу
SIGNAL curr_carry, next_carry: STD_LOGIC;
-- біжуче і наступне значення ознаки нуля
SIGNAL curr_zero, next_zero: STD_LOGIC;
-- вихід для суматора
SIGNAL sum: STD_LOGIC_VECTOR (4 DOWNTO 0);
SIGNAL rorgad: bit_vector (3 DOWNTO 0);
SIGNAL read: STD_LOGIC; -- 1 when reading RAM
SIGNAL write: STD_LOGIC; -- 1 when writing RAM
SIGNAL ior: STD_LOGIC; -- 1 when reading RAM
SIGNAL iow: STD_LOGIC; -- 1 when writing RAM
SIGNAL sel_data_ram: STD_LOGIC; -- 1 when accessing R0-R15
SIGNAL jump_pc: STD_LOGIC; -- 1 when overwriting PC
SIGNAL inc_pc: STD_LOGIC; -- 1 when incrementing PC
SIGNAL ld_ir: STD_LOGIC; -- 1 when loading IR
SIGNAL ld_ir_lsn: STD_LOGIC; -- 1 when loading LSN of IR
-- операція для виконання на ALU
SIGNAL alu_op: STD_LOGIC_VECTOR (3 DOWNTO 0);
--коди операцій
CONSTANT PASS_OP: STD_LOGIC_VECTOR (3 DOWNTO 0):= "0001";
CONSTANT ADD_OP: STD_LOGIC_VECTOR (3 DOWNTO 0):= "0010"; -- add inputs
CONSTANT ROR_OP: STD_LOGIC_VECTOR (3 DOWNTO 0) := "0011";
CONSTANT AND_OP: STD_LOGIC_VECTOR (3 DOWNTO 0):= "0100"; -- test input for 0
CONSTANT SET_CARRY_OP: STD_LOGIC_VECTOR (3 DOWNTO 0) := "0101"; --set carry
CONSTANT CLR_CARRY_OP: STD_LOGIC_VECTOR (3 DOWNTO 0) := "0110"; --clear carry
CONSTANT OR_OP: STD_LOGIC_VECTOR (3 DOWNTO 0):= "0111"; -- XOR inputs
CONSTANT IN_OP: STD_LOGIC_VECTOR (3 DOWNTO 0) := "1000";
CONSTANT OUT_OP: STD_LOGIC_VECTOR (3 DOWNTO 0) := "1001";
CONSTANT CMPL_OP: STD_LOGIC_VECTOR (3 DOWNTO 0):= "1010";
-- біжуча і наступна інструкція
SIGNAL curr_ir, next_ir: STD_LOGIC_VECTOR (7 DOWNTO 0);
-- коди інструкцій
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 ROR_C: STD_LOGIC_VECTOR (7 DOWNTO 0) := "00000100";
CONSTANT IN_PORT: STD_LOGIC_VECTOR (7 DOWNTO 0) := "00001000";
CONSTANT OUT_PORT: STD_LOGIC_VECTOR (7 DOWNTO 0) := "00001001";
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 CMPL_DIR: STD_LOGIC_VECTOR (3 DOWNTO 0) := "0111";
CONSTANT JUMP: STD_LOGIC := '1';
BEGIN
carry_out <= curr_carry;
pc_out <= curr_pc;
acc_out <= curr_acc;
ir_out <= curr_ir;
sel_ram <= sel_data_ram; -- RAM or ROM
-- встановлення сигналів RAM
oeb <= NOT(read); -- CS ROM or read_signal EXT RAM
web <= NOT(write); -- EXT RAM write_signal
io_r <= ior;
io_w <= iow;
-- звернення до пам'яті програм чи до пам'яті даних
address <= "000" & curr_ir(3 DOWNTO 0) WHEN sel_data_ram='1'ELSE
"000" & "1111" WHEN (ior='1'or iow='1')
ELSE curr_pc;
--Пересилає вміст акумулятора в оперативну ПАМ'ЯТЬ протягом операцій запису
--і переводить у високий імпеданс у всіх інших випадках
data <= "0000" & curr_acc WHEN write='1' else "ZZZZZZZZ";
ext_bus<= curr_acc WHEN iow='1'else "ZZZZ";
-- завантажує в регістр інструкцій нове значення
next_ir <= data WHEN ld_ir='1' ELSE
-- або лише чотири молодших біти зданими
curr_ir(7 DOWNTO 4) & data(3 DOWNTO 0) WHEN ld_ir_lsn='1' ELSE
-- в іншому випадку не змінюють IR
curr_ir;
-- завантаження PC для переходу на адресу
next_pc <= curr_ir(6 DOWNTO 0) WHEN jump_pc='1' ELSE
-- або інкрементувати PC
curr_pc+1 WHEN inc_pc='1' ELSE
-- в іншому випадку не змінюють PC
curr_pc;
-- опис ALU
PROCESS (alu_op,curr_zero,curr_carry,curr_acc,curr_ir,sum)
BEGIN
--Встановлює default значення
sum <= "00000";
next_acc <= "0000";
next_carry <= '0';
next_zero <= '0';
CASE alu_op IS
WHEN ADD_OP =>
-- Сумує акумулятор з 4-ма молодшими бітами IR і переносом
sum <= ('0' & curr_acc) + ('0' & curr_ir(3 DOWNTO 0))
+ ("0000" & curr_carry);
next_acc <= sum(3 DOWNTO 0); -- ACC gets lower 4 bits of the sum
next_carry <= sum(4);-- carry is the most significant bit of the sum
next_zero <= curr_zero; -- zero flag is not changed
WHEN ROR_OP =>
-- for CNTR in 0 to 2 loop
-- curr_acc(CNTR)<=curr_acc(CNTR+1);
-- end loop;
next_acc <= curr_carry & (curr_acc(2 downto 0) );
next_carry <= curr_carry;-- carry is the most significant bit of the sum
next_zero <= curr_zero; -- zero flag is not changed
WHEN CMPL_OP =>
if curr_acc=curr_ir(3 DOWNTO 0)then
next_carry <='1';
next_zero <='0';
end if;
next_acc <= curr_acc;-- carry is the most significant bit of the sum
WHEN IN_OP =>
next_acc <= ext_bus; -- ACC gets lower 4 bits of the sum
next_carry <= curr_carry;-- carry is the most significant bit of the sum
next_zero <= curr_zero; -- zero flag is not changed
WHEN OUT_OP =>
ext_bus <= next_acc; -- ACC gets lower 4 bits of the sum
next_carry <= curr_carry;-- carry is the most significant bit of the sum
next_zero <= curr_zero; -- zero flag is not changed
WHEN OR_OP =>
next_acc <= curr_acc OR curr_ir(3 DOWNTO 0);
next_carry <= curr_carry; -- carry flag is not changed
next_zero <= curr_zero; -- zero flag is not changed
WHEN PASS_OP =>
-- Пересилання в акумулятор 4-х молодших бітів IR
next_acc <= curr_ir(3 DOWNTO 0);
next_carry <= curr_carry; -- carry flag is not changed
next_zero <= curr_zero; -- zero flag is not changed
WHEN AND_OP =>
-- test the ACC for zeroes in unmasked bit positions
next_acc <= curr_acc; -- ACC is not changed
next_carry <= curr_carry; -- carry is not changed
-- zero flag is set if ACC has zeroes where IR has ones
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 =>
-- set the carry bit
next_acc <= curr_acc; -- ACC is not changed
next_carry <= '1';
next_zero <= curr_zero; -- zero flag is not changed
WHEN CLR_CARRY_OP =>
-- clear the carry bit
next_acc <= curr_acc; -- ACC is not changed
next_carry <= '0';
next_zero <= curr_zero; -- zero flag is not changed
WHEN OTHERS =>
-- don't do anything for undefined ALU opcodes
next_acc <= curr_acc;
next_carry <= curr_carry;
next_zero <= curr_zero;
END CASE;
END PROCESS;
-- Цей процес описує переходи станів цифрового автомата
-- і встановлює керуючі сигнали у відповідність біжучому стану
PROCESS (curr_st,curr_carry,curr_zero,curr_ir)
BEGIN
-- Встановлення значень за замовчуванням для цих сигналів
-- для уникнення синтезу ініціалізуючих регістрів
sel_data_ram <= '0';
read <= '0';
write <= '0';
ior <= '0';
iow <= '0';
ld_ir <= '0';
ld_ir_lsn <= '0';
inc_pc <= '0';
jump_pc <= '0';
alu_op <= "0000";
CASE curr_st IS
WHEN FETCH =>
-- завантаження інструкції з зовнішньої RAM
sel_data_ram <= '0'; -- select the instruction RAM
read <= '1'; -- read from the RAM
ld_ir <= '1'; -- load the instruction
-- register with the opcode
inc_pc <= '1'; -- increment the PC
-- to the next instruction
next_st <= DECODE; -- then decode the
-- iвиконуємо інструкцію , яка була завнтажена
WHEN DECODE =>
-- декодування інструкції. Фактично, цей стан встановлює
-- читання операнда , заданого прямою адресою , з секції даних
-- зовнішньої оперативної пам'яті і запам'ятовує це значення в молодших 4-х бітах IR.
IF curr_ir(7 DOWNTO 4)=LOAD_DIR THEN
sel_data_ram <= '1';
read <= '1';
ld_ir_lsn <= '1';
END IF;
IF curr_ir(7 DOWNTO 4)=ADD_DIR THEN
sel_data_ram <= '1';
read <= '1';
ld_ir_lsn <= '1';
END IF;
IF curr_ir(7 DOWNTO 4)=CMPL_DIR THEN
sel_data_ram <= '1';
read <= '1';
ld_ir_lsn <= '1';
END IF;
IF curr_ir(7 DOWNTO 4)=IN_PORT THEN
sel_data_ram <= '1';
read <= '1';
ld_ir_lsn <= '1';
END IF;
IF curr_ir(7 DOWNTO 4)=OUT_PORT THEN
sel_data_ram <= '1';
read <= '1';
ld_ir_lsn <= '1';
END IF;
next_st <= EXECUTE; -- виконується інструкція
WHEN EXECUTE =>
-- виконання інструкції.
IF curr_ir=CLEAR_C THEN
alu_op <= CLR_CARRY_OP; -- clear the carry flag
END IF;
IF curr_ir=OUT_PORT THEN
address <="000" & curr_ir(3 downto 0);
iow<='1';
alu_op<="1001";
END IF;
IF curr_ir=IN_PORT THEN
data <="0000" & curr_ir(3 downto 0);
ior<='1';
alu_op<="1000";
END IF;
IF curr_ir=ROR_C THEN
alu_op <= ROR_OP;
END IF;
IF curr_ir=SET_C THEN
alu_op <= SET_CARRY_OP; -- set the carry flag
END IF;
IF curr_ir=SKIP_C THEN -- пропуск наступної інструкції
inc_pc <= curr_carry; -- якщо ознака переносу встановлена
END IF;
IF curr_ir=SKIP_Z THEN -- skip the next instruction
inc_pc <= curr_zero; -- if the zero flag is set
END IF;
IF curr_ir(7 DOWNTO 4)=LOAD_IMM THEN
-- завантаження ACC беспосередньо з молодших 4 біт IR
alu_op <= PASS_OP;
-- data from the lower 4 bits of IR
END IF;
IF curr_ir(7 DOWNTO 4)=ADD_IMM THEN
-- add the lower 4 bits of the
alu_op <= ADD_OP; -- IR to the ACC
END IF;
IF curr_ir(7)=JUMP THEN
-- перейти до адреси зазначеної в молодших 7 бітах IR
jump_pc <= '1';
-- lower 7 bits of the IR
END IF;
IF curr_ir(7 DOWNTO 4)=STORE_DIR THEN
-- записати ACC до RAM
sel_data_ram <= '1';
write <= '1';
END IF;
IF curr_ir(7 DOWNTO 4)=LOAD_DIR THEN
-- завантажити ACC даними що прочиталися з в попередньому циклі
alu_op <= PASS_OP;
END IF;
IF curr_ir(7 DOWNTO 4)=ADD_DIR THEN
-- додати дані з RAM ,що прочиталися в попередньому циклі, до ACC
alu_op <= ADD_OP;
END IF;
IF curr_ir(7 DOWNTO 4)=CMPL_DIR THEN
-- mask the ACC with the value
alu_op <= CMPL_OP;
-- read from RAM in the previous cycle and
END IF;
-- set the zero flag if all the bits are zero
next_st <= FETCH;
-- виконання завершено
WHEN others =>
END CASE;
END PROCESS;
-- Цей процес переписує значення сигналів
-- наступні у бігучі (визначених як дві різні групи сигналів) ,
-- по зростаючому фронту тактового сигналу
PROCESS (clk,reset)
BEGIN
-- Асихронний скид стану GNOME мікрокомп'ютора
IF reset='1' THEN
curr_st <= FETCH; -- start by fetching instructions
curr_pc <= "0000000"; -- start at beginning of instruction RAM
curr_ir <= "00000000";
curr_acc <= "0000"; -- clear accumulator
curr_carry <= '0'; -- clear carry flag
curr_zero <= '0'; -- clear zero flag
-- otherwise, update state on the rising clock edge
ELSIF (clk'event AND clk='1') THEN
curr_st <= next_st;
curr_pc <= next_pc;
curr_ir <= next_ir;
curr_acc <= next_acc;
curr_carry <= next_carry;
curr_zero <= next_zero;
END IF;
END PROCESS;
END gnome_arch;
testbench процесора:
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.std_logic_signed.ALL;
use IEEE.std_logic_arith.ALL;
use std.textio.all;
use ieee.std_logic_textio.all;
entity testbench is
end testbench;
architecture Structura of testbench IS
component gnome is
PORT (
clk: IN STD_LOGIC; -- сигнал синхронізації
reset: IN STD_LOGIC; -- сигнал скиду
address: OUT STD_LOGIC_VECTOR (6 DOWNTO 0); -- лінії адрес зовнішньої RAM
data: INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); -- шина даних
web: OUT STD_LOGIC; -- не дозвіл запису RAM
oeb: OUT STD_LOGIC; -- не дозвіл RAM
sel_ram: out std_logic;
carry_out : out std_logic;
pc_out: OUT STD_LOGIC_VECTOR (6 DOWNTO 0);
ir_out: out std_logic_vector (7 downto 0);
acc_out: out std_logic_vector (3 downto 0)
);
end component gnome;
signal clk:STD_LOGIC; -- сигнал синхронізації
signal reset:STD_LOGIC; -- сигнал скиду
signal address:STD_LOGIC_VECTOR (6 DOWNTO 0); -- лінії адрес зовнішньої RAM
signal data:STD_LOGIC_VECTOR (7 DOWNTO 0); -- шина даних
signal web:STD_LOGIC; -- не дозвіл запису RAM
signal oeb:STD_LOGIC; -- не дозвіл RAM
signal sel_ram:std_logic;
signal carry_out:std_logic;
signal pc_out:STD_LOGIC_VECTOR (6 DOWNTO 0);
signal ir_out:std_logic_vector (7 downto 0);
signal acc_out:std_logic_vector (3 downto 0);
BEGIN
uUT: gnome
port map(
clk=>clk,
reset=>reset,
address=>address,
data=>data,
web=>web,
oeb=>oeb,
sel_ram=>sel_ram,
carry_out=>carry_out,
pc_out=>pc_out,
ir_out=>ir_out,
acc_out=>acc_out
);
StimulCLK:process
begin
if CLK='0'
then CLK<='1';
else CLK<='0';
end if;
wait for 20ns;
end process StimulCLK;
StimulReset:process
begin
Reset<='1';
wait for 70ns;
Reset<='0';
wait;
end process StimulReset;
END Structura;
УГП процесора:
Структурна схема процесора:
EMBED Visio.Drawing.11
Синтез процесора:
=========================================================================
TIMING REPORT
NOTE: THESE TIMING NUMBERS ARE ONLY A SYNTHESIS ESTIMATE.
FOR ACCURATE TIMING INFORMATION PLEASE REFER TO THE TRACE REPORT
GENERATED AFTER PLACE-and-ROUTE.
Clock Information:
------------------
-----------------------------------+------------------------+-------+
Clock Signal | Clock buffer(FF name) | Load |
-----------------------------------+------------------------+-------+
clk | BUFGP | 30 |
-----------------------------------+------------------------+-------+
Timing Summary:
---------------
Speed Grade: -5
Minimum period: 5.978ns (Maximum Frequency: 167.280MHz)
Minimum input arrival time before clock: No path found
Maximum output required time after clock: 9.218ns
Maximum combinational path delay: No path found
Timing Detail:
--------------
All values displayed in nanoseconds (ns)
-------------------------------------------------------------------------
Timing constraint: Default period analysis for Clock 'clk'
Delay: 5.978ns (Levels of Logic = 6)
Source: curr_ir_4 (FF)
Destination: curr_acc_3 (FF)
Source Clock: clk rising
Destination Clock: clk rising
Data Path: curr_ir_4 to curr_acc_3
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
FDCE:C->Q 19 0.494 0.900 curr_ir_4 (curr_ir_4)
LUT4_D:I3->O 5 0.382 0.670 Ker24041 (N2406)
LUT4_D:I3->LO 1 0.382 0.100 Ker24401 (N3858)
LUT4:I0->O 4 0.382 0.650 read_port1 (read_port)
LUT4:I1->O 1 0.382 0.450 next_acc<3>57 (CHOICE173)
LUT4_L:I3->LO 1 0.382 0.100 next_acc<3>58 (CHOICE174)
LUT4_L:I0->LO 1 0.382 0.000 next_acc<3>68 (next_acc<3>)
FDC:D 0.322 curr_acc_3
----------------------------------------
Total 5.978ns (3.108ns logic, 2.870ns route)
(52.0% logic, 48.0% route)
-------------------------------------------------------------------------
Timing constraint: Default OFFSET OUT AFTER for Clock 'clk'
Offset: 9.218ns (Levels of Logic = 5)
Source: curr_ir_4 (FF)
Destination: address<6> (PAD)
Source Clock: clk rising
Data Path: curr_ir_4 to address<6>
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
FDCE:C->Q 19 0.494 0.900 curr_ir_4 (curr_ir_4)
LUT2_D:I0->O 2 0.382 0.610 Ker23041 (N2306)
LUT4:I2->O 2 0.382 0.610 Ker23451 (N2347)
LUT4:I0->O 8 0.382 0.730 sel_data_ram1 (sel_ram_OBUF)
LUT3:I0->O 1 0.382 0.450 Mmux_address_Result<1>1 (address_1_OBUF)
OBUF:I->O 3.896 address_1_OBUF (address<1>)
----------------------------------------
Total 9.218ns (5.918ns logic, 3.300ns route)
(64.2% logic, 35.8% route)
=========================================================================
CPU : 9.30 / 10.98 s | Elapsed : 9.00 / 11.00 s
Часова діаграма роботи процесора
7. Розробка VHDL моделі пам’яті даних
Модель пам’яті даних складено так, аби VHDL синтезатор за стилем написання винайшов, що це можна реалізувати на вбудованих до цільової ПЛІС Віртекс-2 елементах RAM. Це значно збільшує якість реалізації проекту. Існує варіант прямого запису в тексті моделі бібліотечних назв вбудованих до ПЛІС елементів, що треба застосувати. Але тоді цьому модель набуває рис непересувної моделі низького рівня, що не завжди є бажаним. Подамо текст моделі.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ram is
-- Оголошення портів архітектур
port (clk : in std_logic;
oe : in std_logic;
we : in std_logic;
sel_ram : in std_logic;
address : in std_logic_vector(6 downto 0);
data : inout std_logic_vector(7 downto 0));
end ram;
architecture syn of ram is
-- Визначення типу сигналу для реалізації запам'ятовуючої матриці
type ram_type is array (15 downto 0)of std_logic_vector (3 downto 0);
-- Оголошення сигналу RAM
signal RAM : ram_type;
begin
process (clk)
begin
-- Визначення процесу запису RAM
if (clk'event and clk = '1') then
if ((sel_ram = '1')and (oe='1')and (we='0')) then
RAM(conv_integer(address(3 downto 0))) <= data (3 downto 0);
end if;
end if;
end process;
-- Визначення методу читання RAM
data <= "0000"& RAM(conv_integer(address(3 downto 0)))
when ((sel_ram='1') and (oe='0') and (we='1')) else
"ZZZZZZZZ";
end syn;
testbench пам’яті даних:
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.std_logic_signed.ALL;
use IEEE.std_logic_arith.ALL;
use std.textio.all;
use ieee.std_logic_textio.all;
entity testbench is
end testbench;
architecture Structura of testbench IS
component ram is
PORT (
clk : in std_logic;
oe : in std_logic;
we : in std_logic;
sel_ram : in std_logic;
address : in std_logic_vector(6 downto 0);
data : inout std_logic_vector(7 downto 0)
);
end component ram;
signal clk:STD_LOGIC; -- сигнал синхронізації
signal oe:STD_LOGIC; -- не дозвіл RAM
signal we:STD_LOGIC; -- не дозвіл запису RAM
signal sel_ram:std_logic;
signal address:STD_LOGIC_VECTOR (6 DOWNTO 0); -- лінії адрес зовнішньої RAM
signal data:STD_LOGIC_VECTOR (7 DOWNTO 0); -- шина даних
BEGIN
uUT: ram
port map(
clk=>clk,
oe=>oe ,
we=>we,
sel_ram=>sel_ram,
address=>address,
data=>data
);
StimulProcess:process
begin
CLK<='0';
address(3 downto 0)<="0000";
------ read data -------------
wait for 10ns;
CLK<='0';
sel_ram<= '1';
oe<='0';
we<='1';
-----------------
wait for 10ns;
CLK<='1';
---------------------------------
------ write data -------------
wait for 10ns;
CLK<='0';
sel_ram<= '1';
oe<='1';
we<='0';
data(7 downto 0)<="11111111";
-----------------
wait for 10ns;
CLK<='1';
--------------------------------
------ read data -------------
wait for 10ns;
CLK<='0';
sel_ram<= '1';
oe<='0';
we<='1';
-----------------
wait for 10ns;
CLK<='1';
---------------------------------
---------------------------------
wait for 10ns;
CLK<='1';
wait ;
---------------------------------
end process StimulProcess;
END Structura;
УГП пам’яті даних:
Структурна схема пам’яті даних:
EMBED Visio.Drawing.11
Синтез пам’яті даних:
Timing Summary:
---------------
Speed Grade: -5
Minimum period: No path found
Minimum input arrival time before clock: 3.900ns
Maximum output required time after clock: 6.829ns
Maximum combinational path delay: 7.585ns
Timing Detail:
--------------
All values displayed in nanoseconds (ns)
-------------------------------------------------------------------------
Timing constraint: Default OFFSET IN BEFORE for Clock 'clk'
Offset: 3.900ns (Levels of Logic = 3)
Source: oe (PAD)
Destination: RAM_15_3 (FF)
Destination Clock: clk rising
Data Path: oe to RAM_15_3
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
IBUF:I->O 2 0.718 0.610 oe_IBUF (oe_IBUF)
LUT3:I0->O 16 0.382 0.870 _n00351 (_n0035)
LUT4:I3->O 8 0.382 0.730 _n00021 (_n0002)
FDE:CE 0.208 RAM_15_0
----------------------------------------
Total 3.900ns (1.690ns logic, 2.210ns route)
(43.3% logic, 56.7% route)
-------------------------------------------------------------------------
Timing constraint: Default OFFSET OUT AFTER for Clock 'clk'
Offset: 6.829ns (Levels of Logic = 5)
Source: RAM_0_0 (FF)
Destination: data<0> (PAD)
Source Clock: clk rising
Data Path: RAM_0_0 to data<0>
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
FDE:C->Q 1 0.494 0.450 RAM_0_0 (RAM_0_0)
LUT3:I1->O 1 0.382 0.000 Mmux__n0001_inst_lut3_01 (Mmux__n0001__net0)
MUXF5:I0->O 1 0.379 0.000 Mmux__n0001_inst_mux_f5_0 (Mmux__n0001__net2)
MUXF6:I0->O 1 0.389 0.000 Mmux__n0001_inst_mux_f6_0 (Mmux__n0001__net6)
MUXF7:I0->O 1 0.389 0.450 Mmux__n0001_inst_mux_f7_0 (data_0_IOBUF)
IOBUF:I->IO 3.896 data_0_IOBUF (data<0>)
----------------------------------------
Total 6.829ns (5.929ns logic, 0.900ns route)
(86.8% logic, 13.2% route)
-------------------------------------------------------------------------
Timing constraint: Default path analysis
Delay: 7.585ns (Levels of Logic = 6)
Source: address<0> (PAD)
Destination: data<0> (PAD)
Data Path: address<0> to data<0>
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
IBUF:I->O 48 0.718 0.982 address_0_IBUF (address_0_IBUF)
LUT3:I0->O 1 0.382 0.000 Mmux__n0001_inst_lut3_81 (Mmux__n0001__net15)
MUXF5:I0->O 1 0.379 0.000 Mmux__n0001_inst_mux_f5_4 (Mmux__n0001__net17)
MUXF6:I0->O 1 0.389 0.000 Mmux__n0001_inst_mux_f6_2 (Mmux__n0001__net21)
MUXF7:I0->O 1 0.389 0.450 Mmux__n0001_inst_mux_f7_1 (data_1_IOBUF)
IOBUF:I->IO 3.896 data_1_IOBUF (data<1>)
----------------------------------------
Total 7.585ns (6.153ns logic, 1.432ns route)
(81.1% logic, 18.9% route)
=========================================================================
CPU : 8.11 / 9.55 s | Elapsed : 8.00 / 9.00 s
Часова діаграма роботи пам’яті даних:
8. Опис пам’яті програм:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity rom is
port (
sel_ram : in std_logic;
oe : in std_logic;
ADDR : in std_logic_vector (6 downto 0);
DATA : inout STD_LOGIC_VECTOR (7 downto 0));
end rom;
architecture XILINX of rom is
subtype ROM_WORD is STD_LOGIC_VECTOR (7 downto 0);
type ROM_TABLE is array (0 to 30) of ROM_WORD;
constant ROM: ROM_TABLE := ROM_TABLE '(
-------------------------------
ROM_WORD '(x"1B"), -- Load #B
ROM_WORD '(x"04"), -- ROLZ
ROM_WORD '(x"71"), -- JZ #1
-------------------------------
ROM_WORD '(x"00"),
-------------------------------
ROM_WORD '(x"10"),
ROM_WORD '(x"3F"),
ROM_WORD '(x"17"), ----A
ROM_WORD '(x"09"),
---------------------------------------
ROM_WORD '(x"11"),
ROM_WORD '(x"3F"),
ROM_WORD '(x"13"),------B
ROM_WORD '(x"09"),
--------------------------------------
ROM_WORD '(x"12"),
ROM_WORD '(x"3F"), -----Start transfer
ROM_WORD '(x"09"),
------------------------------------
ROM_WORD '(x"13"),
ROM_WORD '(x"3F"), ---Get status transfer
ROM_WORD '(x"08"),
--------------------------
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00"),
ROM_WORD '(x"00")
);
begin
DATA <= ROM(conv_integer (ADDR(5 downto 0)))when (oe='0' and sel_ram='0')
else
"ZZZZZZZZ";
end XILINX;
testbench пам’яті програм:
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.std_logic_signed.ALL;
use IEEE.std_logic_arith.ALL;
use std.textio.all;
use ieee.std_logic_textio.all;
entity testbench is
end testbench;
architecture Structura of testbench IS
component rom is
PORT (
sel_ram : in std_logic;
oe : in std_logic;
ADDR : in std_logic_vector(6 downto 0);
DATA : inout std_logic_vector(7 downto 0)
);
end component rom;
signal sel_ram:std_logic;
signal oe:STD_LOGIC; -- не дозвіл ROM
signal ADDR:STD_LOGIC_VECTOR (6 DOWNTO 0); -- лінії адрес зовнішньої ROM
signal DATA:STD_LOGIC_VECTOR (7 DOWNTO 0); -- шина даних
BEGIN
uUT: rom
port map(
sel_ram=>sel_ram,
oe=>oe ,
ADDR=>ADDR,
DATA=>DATA
);
StimulProcess:process
begin
ADDR<="0000000";
sel_ram<= '0';
oe<='0';
wait for 10ns;
for Counter in 1 to 19 loop
ADDR<="0000001"+ADDR;
wait for 10ns;
end loop ;
wait;
end process StimulProcess;
END Structura;
УГП пам’яті програм:
Структурна схема пам’яті програм:
Синтез пам’яті програм:
EMBED Visio.Drawing.11
=========================================================================
TIMING REPORT
NOTE: THESE TIMING NUMBERS ARE ONLY A SYNTHESIS ESTIMATE.
FOR ACCURATE TIMING INFORMATION PLEASE REFER TO THE TRACE REPORT
GENERATED AFTER PLACE-and-ROUTE.
Clock Information:
------------------
No clock signals found in this design
Timing Summary:
---------------
Speed Grade: -5
Minimum period: No path found
Minimum input arrival time before clock: No path found
Maximum output required time after clock: No path found
Maximum combinational path delay: 6.655ns
Timing Detail:
--------------
All values displayed in nanoseconds (ns)
-------------------------------------------------------------------------
Timing constraint: Default path analysis
Delay: 6.655ns (Levels of Logic = 4)
Source: ADDR<1> (PAD)
Destination: DATA<0> (PAD)
Data Path: ADDR<1> to DATA<0>
Gate Net
Cell:in->out fanout Delay Delay Logical Name (Net Name)
---------------------------------------- ------------
IBUF:I->O 13 0.718 0.830 ADDR_1_IBUF (ADDR_1_IBUF)
LUT4:I1->O 1 0.382 0.000 Mrom__n0001_inst_lut4_01 (Mrom__n0001_inst_lut4_0)
MUXF5:I0->O 1 0.379 0.450 Mrom__n0001_inst_mux_f5_0 (DATA_0_OBUFT)
OBUFT:I->O 3.896 DATA_0_OBUFT (DATA<0>)
----------------------------------------
Total 6.655ns (5.375ns logic, 1.280ns route)
(80.8% logic, 19.2% route)
=========================================================================
CPU : 10.19 / 11.86 s | Elapsed : 10.00 / 12.00 s
Часова діаграма роботи пам’яті даних:
9. Розробка VHDL моделі комп’ютера
В цьому розділі подано структурну VHDL модель комп’ютера. Комп’ютер складено з тьох вузлів – процесора “Гном”, пам’яті програм і пам’яті даних. Вони подані в моделі відповідними компонентами. За допомогою уведених сигналів (дротів і шин) компоненти поєднано поміж собою і з контактвми ПЛІС.
Опис комп’ютера:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- top file
entity gnome_mcu is
Port ( clk : in std_logic;
Reset : in std_logic;
we_view : out std_logic;
carry_view : out std_logic;
oe_view : out std_logic;
sel_ram_view : out std_logic;
pc_view : out std_logic_vector (6 downto 0);
acc_view : out std_logic_vector (3 downto 0);
data_view : out std_logic_vector(7 downto 0);
addr_view : out std_logic_vector(6 downto 0);
ir_view : out std_logic_vector(7 downto 0));
end gnome_mcu;
architecture structural of gnome_mcu is
component gnome port
(
clk: IN STD_LOGIC; -- clock
reset: IN STD_LOGIC; -- reset control input
address: OUT STD_LOGIC_VECTOR (6 DOWNTO 0); -- ext memory addr
data: INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); -- ext memory data bus
--csb: OUT STD_LOGIC; -- active-low chip-select for external RAM
web: OUT STD_LOGIC; -- active-low write-enable for external RAM
oeb: OUT STD_LOGIC; -- active-low output-enable for external RAM
sel_ram: out std_logic;
carry_out : out std_logic;
pc_out: OUT STD_LOGIC_VECTOR (6 DOWNTO 0);
ir_out: out std_logic_vector (7 downto 0);
acc_out: out std_logic_vector (3 downto 0)
);
end component;
component rom port (
sel_ram : in std_logic;
oe : in std_logic;
ADDR : in std_logic_vector (6 downto 0);
DATA : inout STD_LOGIC_VECTOR (7 downto 0));
end component;
component ram port
(clk : in std_logic;
sel_ram : in std_logic;
oe : in std_logic;
we : in std_logic;
address : in std_logic_vector(6 downto 0);
data : inout std_logic_vector(7 downto 0);
data15 : out std_logic_vector(3 downto 0));
end component;
component SerialInterface port
( sel_port : in STD_LOGIC;
iow : in STD_LOGIC;
ior : in STD_LOGIC;
ADDR : in STD_LOGIC_VECTOR(3 downto 0);
DATA : inout STD_LOGIC_VECTOR(3 downto 0);
CLKserial: in STD_LOGIC;
SerialPort: out STD_LOGIC
--selserial: in STD_LOGIC;
--iowserial : in STD_LOGIC;
--iorserial : in STD_LOGIC
);
end component;
signal w_clk: std_logic;
signal w_reset: STD_LOGIC;
signal b_address: STD_LOGIC_VECTOR (6 DOWNTO 0);
sig...