ага, обсчитался :)
Вид для печати
Например, было так:
process(eoc,int_keyb,int_buf)
begin
if eoc='1' then
vector<="11111101";
elsif (int_keyb='1' and int_buf='0') then
vector<="11111011";
end if;
end process;
Это даст лишний варнинг, что vector - это latch. А это не очень хорошо... Можно получить неустойчивую работу из-за "иголок" и "гонок". Делаем так:
process(clock,eoc,int_keyb,int_buf)
begin
if (clock'event and clock='1') then
if eoc='1' then
vector<="11111101";
elsif (int_keyb='1' and int_buf='0') then
vector<="11111011";
end if;
end if;
end process;
Теперь компилятор доволен, а мы избавлены от глюков.
Защелка образуется, например, когда в процессе
есть условия, а присвоение значения производится
не во всех вариантах условия.
http://www.interfacebus.com/Design_VHDL_Pitfalls.html - на англ.
Образно говоря, мы заменяем 555ИР22 на 555ИР23 :)
---------- Post added at 12:06 ---------- Previous post was at 12:03 ----------
Не только...
Защелка записывает в себя данные всё время, пока активен сигнал выбора этой защелки. Если же сделать эту защелку синхронной, т.е. тактировать ее фронтом какого-либо сигнала, то запись будет происходить мгновенно, например как D-триггер, или регистр ИР23.
Делается делителем на 4 и элементом "Исключающее ИЛИ"
http://library.espec.ws/books/ttl/CHAPTER2/2-4-3.htm
Ewgeny7, в твоём файле orionkeyboard.v есть вот такие конструкции:
Эти два массива различные? Если да, то почему они названы одинаково или это в синтаксисе языка дозволено? Первый индекс означен номер столбца, второй - строки или наоборот?Цитата:
...
keymatrix[7] <= 8'h0;
...
9'h06c: keymatrix[0][0] <= press_release; //Home
...
Я почему спрашиваю. Для реализации клавиатуры в Специалисте, мне приходится перелопачивать весь текст программы, т.к. приходится описывать клавиатуру 12 на 6. В программе учитывается ли что русская и английская раскладка на одних и тех же клавишах не совпадают?
Да, keymatrix это массив 8х8. Синтаксис позволяет описывать как любой "бит" массива, так и строчку целиком. Что там строка а что столбец - я уже не помню, надо схему РК-клавиатуры смотреть.
Я приспосабливал этот блок для спектрума, исправлений было достаточно (5х8). Символы переписывал долго :) Выкладывал готовый блок где-то здесь в теме.
Нет. В Орионе нет четкого сигнала, указывающего на выбранную раскладку. Если бы был, то добавить удобную для себя раскладку - не проблема. Всего лишь сделать вторую таблицу символов :)
А так как есть - только ЯВЕРТЫ.
Всё ж, массив который одномерный как-то отличается от двухмерного или это один и тот же массив?
У меня есть этот файл - посмотрю.
Жаль. А вот в Специалисте есть клавиша РУС/LAT - можно же по нажатию её организовать триггер состояния клавиатуры?
Так в Специалисте есть светодиод "РУС/LAT"...
Вроде добил драйвер клавиатуры, просмотрите. В нем - metod - метод опроса клавиатуры:
=0 - порт А и мл. тетрада порта С - на вывод, порт В - на ввод;
=1 - порт В - на вывод, порт А и мл. тетрада порта С - на ввод.
Работает?
Да нет, пока у меня железки нет,прогу пишу...
Ewgeny7, при компиляции программы большинство варнингов (30) выдается на файл ps2_keyboard.v. Что это за ошибки?
Цитата:
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(321): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(332): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(333): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(338): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(339): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(341): truncated value with size 32 to match size of target (1)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(359): truncated value with size 32 to match size of target (4)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(388): truncated value with size 32 to match size of target (12)
Warning (10230): Verilog HDL assignment warning at ps2_keyboard.v(396): truncated value with size 32 to match size of target (8)
Не получится. ОЗУ на Специалисте должно с видео ОЗУ цвета иметь нелинейную структуру т.е. 48 кБайт + 12 кБайт. Если расширять до МХ то еще 512 кБайт опять в другом месте. Так что это две срамины, причем одна из них 16 байт ввода/вывода с параллельной шиной адреса и управлением. ПЗУ должно быть от 12 кБайт до 512 кБайт (МХ). Вот посмотрите схему - http://www.spetsialist-mx.ru/for_out/NewSpets.gif. Спасибо конечно за предложение.
Может быть, но я файл взял с проект Орион-2010. У Ewgeny7 таких варнингов нет?
Почему-то ранее не встречал таблички для VHDL, где были бы расписаны
приоритеты операторов, знаков и т.п., т.е. в какой последовательности
производится разбор сложных выражений.
(Это позволит пресечь злоупотребление скобочками, между IF и THEN, например ;) )
Исправляем ситуацию:
and, or, nand, nor, xor – самый низкий приоритет
=, /=, <, <=, >, >=
+, -, & (бинарные)
+, - (унарные)
*, /, mod, rem
abs, not – высший приоритет
Операторы с более высоким приоритетом выполняются раньше. Чтобы изменить такой порядок используются скобки.
Что может давать такие искажения? если бордер будет черный - искажение мене выражено
(создано на ФПГА, картинка берется из ПЗУ, вывод на ВГА, тайминги приближены к его стандарту - не скандаблер)
Я бы проверил гашение в интервалах между строками.Цитата:
если бордер будет черный - искажение мене выражено
Файлы нужно смотреть. Похоже на то, что селекторы синхроимпульсов не имеют привязки к клоку.
По человечески это звучит так.
Имеются у нас счетчики пикселей/строк. Тактируются клоком. Но при этом после очередного клока эти счетчики еще какое-то время "устаканиваются". Но за это небольшое время их значение будет "колбаситься" весьма основательно, возникают ложные значения. Если формирователь синхры у нас сделан примерно так:
hsyn<='0' when (vcnt>224) and (vcnt<228) else '1';
то будут ложные переключения значения hsyn.
Если так:
process(vcnt)
begin
if vcnt=224 then
hsyn<='0';
elsif vcnt=228 then
hsyn<='1';
end if;
end process;
то результат может быть еще хуже, импульс hsyn может растянуться на изрядное пространство фрейма, притом в неположенном месте. Да и "защелка" ("latch") hsyn лишняя совершенно не нужна, ПЛИСы их очень не любят.
Поэтому лучше дать кусочек времени счетчикам для "успокоения значения". Для этого применяем тот же клок. В результате мы прочитаем значение на период (или полпериода) позже, зато чётко и надежно. Заодно latch превратится в обычный синхронный триггер, что само по себе очень хорошо :) :
process(clk,vcnt)
begin
if (clk'event and clk='1') then
if vcnt=224 then hsyn<='0'; end if;
if vcnt=228 then hsyn<='1'; end if;
end if;
end process;
а как тогда задать hsync='1' всегда кроме описанного примера выше, или по другому, до того как сменить значение на '0', hsync должен выдавать '1' ?. или это не нужно ( все равно после первой строки все войдет в норму)?
у меня сейчас вот так:
process (CLK,hcnt)
begin
if (CLK'event and CLK='1') then
---
if (hcnt>=320 and hcnt<382) then HSYNC<='0';
else HSYNC<='1';
end if;
---
if (hcnt>=312 and hcnt<400) then HBLANC<='1';
else HBLANC<='0';
end if;
---
if (hcnt>=8 and hcnt<264) then HSCR<='1';
else HSCR<='0';
end if;
---
if hcnt=448 then HRST<='1';
else HRST<='0';
end if;
---
end if;
end process;
но по твоему мне как то больше нравиться, все четко и понятно.
переписал свои селекторы вот так:
process (CLK,hcnt)
begin
if (CLK'event and CLK='1') then
---
if hcnt=320 then HSYNC<='0'; end if;
if hcnt=382 then HSYNC<='1'; end if;
-- if (hcnt>=320 and hcnt<382) then HSYNC<='0';
-- else HSYNC<='1';
-- end if;
---
if hcnt=312 then HBLANC<='1'; end if;
if hcnt=400 then HBLANC<='0'; end if;
-- if (hcnt>=312 and hcnt<400) then HBLANC<='1';
-- else HBLANC<='0';
-- end if;
---
if hcnt=8 then HSCR<='1'; end if;
if hcnt=264 then HSCR<='0'; end if;
-- if (hcnt>=8 and hcnt<264) then HSCR<='1';
-- else HSCR<='0';
-- end if;
---
if hcnt=448 then HRST<='1';
else HRST<='0';
end if;
---
end if;
end process;
это по горизонтали (закоментил старый вариант)
и так:
process (CLK,vcnt)
begin
if (CLK'event and CLK='1') then
---
if vcnt=224 then VSYNC<='0'; end if;
if vcnt=225 then VSYNC<='1'; end if;
-- if vcnt=224 then VSYNC<='0';
-- else VSYNC<='1';
-- end if;
---
if vcnt=216 then VBLANC<='1'; end if;
if vcnt=241 then VBLANC<='0'; end if;
-- if (vcnt>=216 and vcnt<241) then VBLANC<='1';
-- else VBLANC<='0';
-- end if;
---
if vcnt<192 then VSCR<='1';
else VSCR<='0';
end if;
---
if vcnt=264 then VRST<='1';
else VRST<='0';
end if;
---
end if;
end process;
по вертикали (в коментах также старый вариант)
и как итог - опять появились срывы, но вот почему только в середине экрана(вторая из трех частей) ума не приложу...... на ЖКИ 22" вайдскрин - теже пилы видны, что и на стареньком ВГА 14". опять в легком тупнике...
aniSKY, извини, а сколько строк у тебя по вертикали выходит?
Да и кадровый "толщиной" в одну строку как-то смущает...
по вертикали 264(или 528 если весь счетчик брать, я беру только начиная с с 1го разряда)
кадровый - если брать все разряды то получится две строки, просто 0й разряд не беру в расчет.
опишу в общем весь проект - смесь схемного ввода с кусками на ВХДЛ, пытался на чистом ВХДЛ, но начинаю путаться, мне схемный немного ближе, визуально более понятен, да и та часть что сдвигает пиксели (сдвиговый регистр пикселей) так и не поддается мне....:v2_blush:
на всякий пожарный мой проект по частям:
может кто поможет в написании мультиплексора, коммутирующего двунаправленную шину к двунаправленной или к шине на вывод по сигналу выбора какимнить маленьким примером? а возможно ли такое?
з.ы. хочется подрубить свою поделку к компутеру, а в двунаправленности шин в ВХДЛ все никак не разберусь....ток сильно не пинайте, на конкретных примерах както проще разобраться.
Для затравки выкладываю пример:
двунаправленный порт FF (условно, конечно), проц его читает и туда пишет;
Если для записи и чтения порты разные, но номер одинаковый, то в процессах пишем в один сигнал, читаем из другого (его нужно добавить).
Код:-- ПЛИС <-> Z80 чтение-запись порта, например, FF
port (
signal iAddrZXbus : in std_logic_vector (15 downto 0);
signal ioDataZXbus : inout std_logic_vector (7 downto 0);
signal iIorqZXbus : in std_logic;
signal iRdZXbus : in std_logic;
signal iWrZXbus : in std_logic;
signal iM1ZXbus : in std_logic; -- добавить, чтобы не срабатывал при подтв.прерывания
signal iResetZXbus : in std_logic;
signal iFZXBus : in std_logic ) -- тактовый 14 МГц
signal sIoWr : std_logic;
signal sIoRd : std_logic;
signal A1,A2 : std_logic;
signal sFF : std_logic_vector (7 downto 0);
sIoWr <= iIorqZXbus or iWrZXbus;
sIoRd <= iIorqZXbus or iRdZXbus;
process (iFZXbus)
begin
if iReset = '0' then
ioDataZXbus <= (others => 'Z');
elsif rising_edge(iFZXbus) then
A1 <= sIoWr;
A2 <= not A1;
if sIoRd = '0' and iAddrZXbus = x"00FF" then
ioDataZXbus <= sFF;
else
ioDataZXbus <= (others => 'Z');
end if;
if (A1 or A2) = '0' and iAddrZXbus = x"00FF" then
sFF <= ioDataZXbus;
end if;
end if;
end;
aniSKY, то есть, все понятно? Могу прокомментировать.
Код я не проверял, но, по идее, должен работать.
Нужно еще сделать проверку на /IORQ и M1,
чтобы не реагировало на подтверждение прерывания
(это надо в доке на проц уточнить).
aniSKY, что-то я не понял у тебя в блоках hsgen.vhd и vsgen.vhd отсутствует приращение горизонтальных и вертикальных счётчиков. Забыл? Еще одна ошибка. На выходе элемента И (inst20) всегда будет 0. Это в формировании сигнала PINF.
fifan, не, счетчики строк/пикселей в графическом блоке. В текстовиках только селекторы синхры.
эт пока счетчик на ФЛЭШ не добавлен, позже допишу, как более менее заработает буду подчищать, по возможности в ВХДЛ переписывать:)
---------- Post added at 20:36 ---------- Previous post was at 20:33 ----------
на 100% еще наверно нет, просто как пример использовании двунаправленных портов/сигналов/шин (или как там правильнее) немного прояснил, а мысли пошли думать дальше....:v2_thumb:
---------- Post added at 20:42 ---------- Previous post was at 20:36 ----------
если можно в краце пояснить данную конструкцию:
if iReset = '0' then
ioDataZXbus <= (others => 'Z');
elsif rising_edge(iFZXbus) then
... далее по примеру
ioDataZXbus <= (others => 'Z'); -- как это описывается словами? (правильно наверно (others) ?)