Важная информация

User Tag List

Страница 5 из 9 ПерваяПервая 123456789 ПоследняяПоследняя
Показано с 41 по 50 из 88

Тема: Потактовый клон Денди на FPGA

  1. #41
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    А как наличие общего счетчика может пострадать от перевода с двухфазной модели на однофазную синхронную?

  2. #42
    Master Аватар для s_kosorev
    Регистрация
    19.06.2014
    Адрес
    г. Харьков, Украина
    Сообщений
    731
    Спасибо Благодарностей отдано 
    6
    Спасибо Благодарностей получено 
    16
    Поблагодарили
    15 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Убедил самого себя

  3. #43
    Guru
    Регистрация
    16.12.2008
    Адрес
    Kharkov, Ukraina
    Сообщений
    2,221
    Спасибо Благодарностей отдано 
    4
    Спасибо Благодарностей получено 
    21
    Поблагодарили
    18 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    А я бы начал с инициализации сего хитрого девайса. Это очевидно для профи. А чайники потом будут репу чухать. Тем более будет не лишним описать с чего, все стартует. И о блоках(чипа) немного.

    Вроде по делу. Простите за мой ломаный английский.
    Электроника КР-02, MSX YIS-503IIR, Орион-128, Ленинград-2, Pentagon-128k, MSX2 YIS-503IIIR, MSX-EXT, ...

  4. #44
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Сегодня мы разберем системные регистры. Это два регистра, с индексами 0 и 1, которые задают режим работы всего PPU. Собственно, регистры как регистры, сохраняют входящие от CPU данные, синхронизируют их с ядром PPU и выдают их этому ядру. Назначение бит этих регистров следующее:
    Регистр #0:
    D7 - VBL Разрешение генерации на ноге #19 сигнала низкого уровня после отрисовки растра, которая подключена ко входу NMI CPU (прерывание VBlank).
    D6 --- Отсутствует
    D5 - O8_16 Высота спрайтов, если 0 то 8 точек, если 1 то 16 точек.
    D4 - BGSEL Старший бит адреса знакогенератора для тайлов фона (0ххх/1xxx).
    D3 - OBSEL Cтарший бит адреса знакогенератора для спрайтов (0xxx/1xxx).
    D2 - I1_32 Приращение адреса при достпуе к VRAM: 0 - 1, 1 - 32 (для рисования горизонтальных или вертикальных линий).
    D1, D0 Выбор старшего адреса для таблицы имен тайлов фона (номер экрана), эти биты обрабатываются в формирователе адреса VRAM.
    Регистр #1:
    D7 - EmB Приглушение синих оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
    D6 - EmG Приглушение зеленых оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
    D5 - EmR Приглушение красных оттенков, буржуи называют это эмпфазисом, подробнее о нем будет при разборе видео ЦАП.
    D4 - OBE Включение отображения спрайтов.
    D3 - BGE Включение отображения фона.
    D2 - OBCLIP Гашение столбца из левых 8 точек на плоскости спрайтов.
    D1 - BGCLIP Гашение столбца из левых 8 точек на плоскости фона.
    D0 - B_W Отключение вывода оттенков (Ч/Б вывод изображения).
    Оригинальная схема "влоб":

    Оптимизированная синхронная схема:

    Функциональный аналог Verilog:
    Код:
    // Системные регистры 0 / 1
    module PPU_SYS_REGS(
        // Системные входы
        input    Clk,            // Тактовая частота
        input    PClk,           // Пиксельклок
        // Управляющие входы
        input    W0,             // Запись в регистр 0
        input    W1,             // Запись в регистр 1
        input    [7:0]DBIN,      // Данные
        // Выходы
        output   reg I1_32,      // Увеличение адреса +1/+32 (H/V)
        output   reg OBSEL,      // Старший бит адреса знакогенератора спрайтов
        output   reg BGSEL,      // Старший бит адреса знакогенератора фона
        output   reg O8_16,      // Высота спрайтов (0 - 8 точек, 1 - 16 точек)
        output   reg VBL,        // Разрешение прерывания VBlank
        output   reg B_W,        // Режим Ч/Б (обнуление младших 4х битов индекса цвета)
        output   reg BGCLIP,     // Гашение левого столбца 8 точек у фона
        output   reg OBCLIP,     // Гашение левого столбца 8 точек у спрайтов
        output   reg BGE,        // Включение фона
        output   reg OBE,        // Включение спрайтов
        output   reg EmR,        // Эмпфазис красного цвета
        output   reg EmG,        // Эмпфазис зеленого цвета
        output   reg EmB         // Эмпфазис синего цвета
    );
    // Промежуточные регистры
    reg [4:0]W0R;
    reg [7:0]W1R;
    // Логика
    always @(posedge Clk) begin
        if (PClk) begin
            // Запись значения в промежуточные регистры
            if (W0) W0R[4:0] <= {DBIN[7],DBIN[5:2]};
            if (W1) W1R[7:0] <= DBIN[7:0];
            // Обновление значений
            if (~W0) {VBL,O8_16,BGSEL,OBSEL,I1_32} <= W0R[4:0];
            if (~W1) {EmB,EmG,EmR,OBE,BGE,OBCLIP,BGCLIP,B_W} <= W1R[7:0];
            end
    end
    // Конец
    endmodule
    Обратите внимание, что я не использую тактовый сигнал PClk (позитивный пиксельклок) как сигнал чувствительности always блока. Промежуточная модель его именно так и использовала, но в строго синхронной модели этого быть не должно. Тактовая частота должна быть одна во всем дизайне. PClk же становится сигналом разрешения, длительностью строго в 1 такт главной тактовой частоты Clk и периодичностью нужные нам 4 такта для NTSC PPU (или 5 тактов для PAL PPU). Эта же тенденция будет сохраняться и для остальных блоков.
    Последний раз редактировалось HardWareMan; 20.10.2017 в 17:36.

  5. #45
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Savepic сдох. Прежде чем перейти к следующему блоку, я попытаюсь восстановить картинки.

  6. #46
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Сэйвпик ожил, дублирую фотки себе, в теме буду хостить у себя на всякий случай.

  7. #46
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  8. #47
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Руки дошли, схоронил все картинки. Готовлю следующую тему по мере сил и времени.

  9. #48
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Давно я ничего сюда не постил, а время то летит....

    Блоки, входными сигналами которых были только внешние сигналы, закончились. Сегодня поговорим о сердце PPU: о синхрогенераторе. Это "сердце" PPU, он дирижирует остальными блоками.

    Входные сигналы:
    Clk - Главный тактовый сигнал
    OBCLIP - Обрезание левой части экрана спрайтов
    BGCLIP - Обрезание левой части экрана фона
    BGE - Активация фона
    OBE - Активация спрайтов
    VBL - Разрешение запроса прерывания VBlank
    R2 - Чтение регистра 2
    nRES - Общий сброс PPU

    Выходные сигналы:
    PClk - Пиксельклок
    ALEGate - Гейт ALE
    [5:0]HNN - Синхронизированное атомарное состояние PPU
    S_EV - Запуск процесса просмотра списка спрайтов
    CLIP_O - Гашение левого столбца из 8ми точек экрана для спрайтов
    CLIP_B - Гашение левого столбца из 8ми точек экрана для фона
    O_HPOS - Запуск счетчиков координаты X спрайтов (позиция 0 спрайтов)
    EVAL - Сброс счетчика OAMT и начало процесса обработки OAMT
    E_EV - Инициализация схемы адреса для вычитания графики спрайтов
    I_OAM2 - Сигнал очистки OAMT
    PAR_O - Вычитывание графики спрайтов
    VIS - Маска активного растра (графика выводится на экран)
    F_NT - Чтение Name Table
    F_TB - Чтение второго байта
    F_TA - Чтение первого байта
    N_FO - Сигнал разрешения вывода графики фона
    F_AT - Чтение атрибутов из Name Table
    SC_CNT - Запуск счетчика адресов при включении растра и/или фона
    BURST - Маска вывода вспышки синхронизации поднесущей цвета
    SYNC - Синхросмесь видеосигнала
    PICTURE - Маска выводимого изображения
    N_INT - NMI прерывание по VBLANK
    R2B7 - Чтение флага NMI
    BLNK - Гашение
    RESCL - Строка пререндера (сброс всех схем выборки)
    [7:0]V - Выход вертикального счетчика (для спрайтовой машины)
    HSYNC - Выход строчной синхронизации
    VSYNC - Выход кадровой синхронизации

    Синхрогенератор содержит 2 счетчика: горизонтальный и вертикальный. Горизонтальный считает пиксели (по пиксельклоку) а вертикальный - строки растра. Каждый сигнал имеет четкую координату Пиксель:Строка, которая в оригинальной схеме задана обычной матрицей:


    Я не буду более детально расписывать каждый вырабатываемый сигнал. Это лучше сделать при описании модулей, где конкретный сигнал используется.

    По традиции, схема "влоб":


    Оптимизированная схема:


    Verilog код:
    Код:
    // Главный счетчик таймингов PPU
    module PPU_HV_COUNTER(
    	// Системные входы
    	input	Clk,			// Главные такты
    	// Входные цепи
    	input	OBCLIP,			// Обрезание левой части экрана спрайтов
    	input	BGCLIP,			// Обрезание левой части экрана фона
    	input	BGE,			// Активация фона
    	input	OBE,			// Активация спрайтов
    	input	VBL,			// Разрешение запроса прерывания VBlank
    	input	R2,				// Чтение регистра 2
    	input	nRES,			// Общий сброс PPU
    	// Выходные цепи
    	output	reg PClk,		// Пиксельклок
    	output	reg ALEGate,	// Гейт ALE
    	output	reg [5:0]HNN,	// Синхронизированное атомарное состояние PPU
    	output	reg S_EV,		// Запуск процесса просмотра списка спрайтов
    	output	reg CLIP_O,		// Гашение левого столбца из 8ми точек экрана для спрайтов
    	output	reg CLIP_B,		// Гашение левого столбца из 8ми точек экрана для фона
    	output	reg O_HPOS,		// Запуск счетчиков координаты X спрайтов (позиция 0 спрайтов)
    	output	reg EVAL,		// Сброс счетчика OAMT и начало процесса обработки OAMT
    	output	reg E_EV,		// Инициализация схемы адреса для вычитания графики спрайтов
    	output	reg I_OAM2,		// Сигнал очистки OAMT
    	output	reg PAR_O,		// Вычитывание графики спрайтов
    	output	reg VIS,		// Маска активного растра (графика выводится на экран)
    	output	reg F_NT,		// Чтение Name Table
    	output	reg F_TB,		// Чтение второго байта
    	output	reg F_TA,		// Чтение первого байта
    	output	reg N_FO,		// Сигнал разрешения вывода графики фона
    	output	reg F_AT,		// Чтение атрибутов из Name Table
    	output	SC_CNT,			// Запуск счетчика адресов при включении растра и/или фона
    	output	reg BURST,		// Маска вывода вспышки синхронизации поднесущей цвета
    	output	reg SYNC,		// Синхросмесь видеосигнала
    	output	PICTURE,		// Маска выводимого изображения
    	output	N_INT,			// NMI прерывание по VBLANK
    	output	reg R2B7,		// Чтение флага NMI
    	output	BLNK,			// Гашение
    	output	reg RESCL,		// Строка пререндера (сброс всех схем выборки)
    	output	[7:0]V,			// Выход вертикального счетчика (для спрайтовой машины)
    	output	reg HSYNC,		// Выход строчной синхронизации
    	output	reg VSYNC		// Выход кадровой синхронизации
    );
    // Переменные
    reg [1:0]ClkDiv;			// Предделитель тактов
    reg [8:0]HCnt;				// Строчный счетчик
    reg [8:0]VCnt;				// Кадровый счетчик
    reg V8R;					//
    reg Odd;					// Чет/нечет
    reg VB;						// Вертикальное
    reg FPORCH;
    reg BPORCH;
    reg N_HB;
    reg BREN;
    reg VSNC;
    reg PEN;
    reg [2:0]IFIFO;
    reg IREQ;
    reg R2R;
    reg BLNKR;
    // Комбинаторика
    assign SC_CNT = ~N_HB & (BGE | OBE);
    assign PICTURE = ~PEN & ~BPORCH;
    assign N_INT = ~(IREQ & VBL);
    assign BLNK = BLNKR | ~(BGE | OBE);
    assign V[7:0] = VCnt[7:0];
    // Логика
    always @(posedge Clk) begin
    	// Синхронизация
    	R2R <= R2; V8R <= VCnt[8]; 
    	// Запрос прерывания
    	if (~IFIFO[0] & ~IFIFO[2]) IREQ <= 1'b1;
    		else if (R2R | RESCL) IREQ <= 1'b0;
    	// Флаг прерывания
    	if (~R2R & ~R2) R2B7 <= IREQ;
    	// Флаг Odd
    	if (V8R & ~VCnt[8]) Odd <= ~Odd;
    	// Делитель частоты
    	ClkDiv[1:0] <= ClkDiv[1:0] + 2'h1;
    	// Активация пиксельклока строго на 1 такт
    	PClk <= ClkDiv[1] & ClkDiv[0];
    	// Маска сигнала ALE
    	ALEGate <= ~ClkDiv[1];
    	// Пиксельклок
    	if (PClk) begin
    		// Синхронизация
    		HNN[5:0] <= HCnt[5:0];
    		// Счетчик строк
    		if (~nRES | (HCnt[8:0] == 9'd340) | (Odd & (HCnt[8:0] == 9'd339) & RESCL)) begin
    			// Строка досчитала, обрабатываем
    			HCnt[8:0] <= 9'd000;
    			// Счетчик кадров
    			if (~nRES | (VCnt[8:0] == 9'd261)) VCnt[8:0] <= 9'd000; else VCnt[8:0] <= VCnt[8:0] + 9'd001;
    			end else HCnt[8:0] <= HCnt[8:0] + 9'd001;
    		// Сигнал N_FO - Переключение между графикой и служебной информацией
    		N_FO <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4])));
    		// Сигнал S_EV
    		S_EV <= ~BLNK & (HCnt[8:0] == 9'd065);
    		// Сигналы отсечения
    		CLIP_O <= ~OBCLIP & (~(HCnt[8] | VB) & ~HCnt[7] & ~HCnt[6] & ~HCnt[5] & ~HCnt[4] & ~HCnt[3]);
    		CLIP_B <= ~BGCLIP & (~(HCnt[8] | VB) & ~HCnt[7] & ~HCnt[6] & ~HCnt[5] & ~HCnt[4] & ~HCnt[3]);
    		// Сигнал позиции
    		O_HPOS <= ~BLNK & (HCnt[8:0] == 9'd339);
    		// Сигнал EVAL
    		EVAL <= ~BLNK & ((HCnt[8:0] == 9'd339) | (HCnt[8:0] == 9'd063) | (HCnt[7:0] == 8'd255));
    		// Сигнал E_EV
    		E_EV <= ~BLNK & (HCnt[7:0] == 8'd255);
    		// Сигнал I_OAM2
    		I_OAM2 <= ~BLNK & ~HCnt[8] & ~HCnt[7] & ~HCnt[6];
    		// Сигнал PAR_O
    		PAR_O <= ~BLNK & HCnt[8] & ~HCnt[7] & ~HCnt[6];
    		// Сигнал VIS
    		VIS <= ~VB & ~HCnt[8] & ~BLNK;
    		// Сигнал F_NT - Чтение таблицы символов
    		F_NT <= ~BLNK & ~HCnt[2] & ~HCnt[1];
    		// Сигнал F_TB - Чтение второго байта графики
    		F_TB <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & HCnt[2] & HCnt[1];
    		// Сигнал F_TA - Чтение первого байта графики
    		F_TA <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & HCnt[2] & ~HCnt[1];
    		// Сигнал F_AT - Чтение атрибутов
    		F_AT <= ~(BLNK | (HCnt[8] & (~HCnt[6] | HCnt[5] | HCnt[4]))) & ~HCnt[2] & HCnt[1];
    		// Сигнал HSYNC
    		HSYNC <= FPORCH;
    		// Сигнал VSYNC
    		VSYNC <= ~VSNC & ~N_HB;
    		// Сигнал SYNC
    		SYNC <= FPORCH | (~VSNC & ~N_HB);
    		// Сигнал BURST
    		BURST <= BREN & (FPORCH | (~VSNC & ~N_HB));
    		// Сигнал PEN
    		if (VCnt[7:0] == 8'd241) PEN <= 1'b1;
    			else if (VCnt[8:0] == 9'd261) PEN <= 1'b0;
    		// Сигнал BPORCH
    		if (HCnt[8:0] == 9'd270) BPORCH <= 1'b1;
    			else if (HCnt[8:0] == 9'd328) BPORCH <= 1'b0;
    		// Сигнал VB
    		if (VCnt[8:0] == 9'd261) VB <= 1'b0;
    			else if (VCnt[7:0] == 8'd239) VB <= 1'b1;
    		// Сигнал BLNKR
    		if (VCnt[8:0] == 9'd261) BLNKR <= 1'b0;
    			else if (VCnt[7:0] == 8'd240) BLNKR <= 1'b1;
    		// Сигнал FPORCH
    		if (HCnt[8:0] == 9'd256) FPORCH <= 1'b1;
    			else if (HCnt[8:0] == 9'd279) FPORCH <= 1'b0;
    		// Сигнал N_HB
    		if (HCnt[8:0] == 9'd279) N_HB <= 1'b1;
    			else if (HCnt[8:0] == 9'd304) N_HB <= 1'b0;
    		// Сигнал BREN
    		if (HCnt[8:0] == 9'd308) BREN <= 1'b1;
    			else if (HCnt[8:0] == 9'd323) BREN <= 1'b0;
    		// Сигнал VSNC
    		if (N_HB) begin
    			if (VCnt[8:0] == 9'd244) VSNC <= 1'b1;
    				else if (VCnt[8:0] == 9'd247) VSNC <= 1'b0;	// FIFO запроса прерывания
    			end
    		IFIFO[2:0] <= {~IFIFO[1],IFIFO[0],~(VCnt[7:0] == 8'd241)};
    		// Сигнал RESCL
    		RESCL <= (VCnt[8:0] == 9'd261);
    		end
    end
    
    // Конец
    endmodule
    Последний раз редактировалось HardWareMan; 21.10.2017 в 10:40.

  10. #49
    Guru Аватар для HardWareMan
    Регистрация
    26.02.2011
    Адрес
    г. Павлодар, Казахстан
    Сообщений
    4,395
    Спасибо Благодарностей отдано 
    304
    Спасибо Благодарностей получено 
    594
    Поблагодарили
    440 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Блок формирования управляющих сигналов локальной шины PPU.

    Локальная шина PPU это отдельное адресное пространство для памяти, которая хранит текущее состояние картинки. Она состоит из младшего байта адреса и данных, мультиплексированных между собой в сигналы PPU_AD[7..0], старших 6ти бит адреса PPU_A[13..8] и сигналов управления: PPU_ALE для защелкивания адреса на шине PPU_AD[7..0], ~PPU_RD для строба чтения данных и ~PPU_WR для строба записи данных. Направление указано со стороны PPU. Для упрощения, я их буду называть так: PAD[7..0], PA[13..8], ALE, PRD и PWR (на схемах RD и WR соответственно).
    - 2 знакогенератора, младшие 8 КБайт: 0000-0FFF и 1000-1FFF.
    - 4 т.н. "таблицы имён" (Name Tables, это название появилось из-за тайлового метода формирования изображения PPU: в "таблице имен" заносится код символа из знакогенератора, который потом и отображается на текущем месте тайла, совсем как текст у ВГ75), по 1 КБайту на страницу: 2000-23FF, 2400-27FF, 2800-2BFF и 2C00-2FFF. В каждой странице есть сама страница тайлов x000-x3BF и таблица атрибутов 0x3C0-x3FF.
    - 4 палитры фона: 3F00-3F0F
    - 4 палитры спрайтов: 3F10-3F1F
    Остальные неуказанные области просто не используются. Причем, так как ОЗУ палитры находится внутри PPU то генерация внешних сигналов PRD и PWR не производится, при обращении к области 3F00-3FFF, но область 3000-3EFF программно доступна через регистр #7. Вот схема "влоб":

    Сигналы обращения к регистру #7 проходят через синхронизатор и формирователь нужного тайминга для локальной шины PPU. Каждое обращение к регистру #7 формирует строб увеличения счетчика адреса TSTEP, который может влиять на счетчики даже если происходит вывод растра (тот самый конфликт при обращении к VRAM за пределами кадрового гашения). Сигнал DB_PAR сопровождает сигнал записи PWR и сигнализирует о том, что необходим проброс данных с шины CPU D[7..0] на локальную шину PAD[7..0]. Сигнал PD_RB указывает на чтение с шины PAD[7..0] внутрь PPU, и, в зависимости от источника запроса (R7 или синхрогенератор) перенаправляет данные на шину CPU D[7..0] (на это указывает сигнал XRB) или в рабочие регистры или счетчики растра PPU. Сигнал THX_MUX вырабатывается если текущий адрес PA[13..8] равен 3F (обращение к внутреннему ОЗУ палитры) и блокирует внешний сигнал записи PWR а так же сигнал XRB.
    Оптимизированная схема:

    Здесь появился новый входной сигнал ALEGate, который был введен в рамках организации синхронного дизайна проекта, так как в оригинальной схеме сигнал ALE для режима синхрогенератора (чтение данных растра) организовано как OR сигнала атомарного состояния PPU H0n и инвертированного тактового сигнала PCLK. В синхронной схеме сигнал ALEGate заменяет инвертированный тактовый сигнал PCLK, делая схему строго синхронной. Verilog код модуля:
    Код:
    // Управление модулями по адресу
    module PPU_ADR_CONTROL(
    	// Системные входы
    	input	Clk,			// Системные такты
    	input	PClk,			// Такты пикселей
    	input	ALEGate,		// Формирователь сигнала ALE
    	// Управляющие входы
    	input	W7,				// Запись в регистр 7
    	input	R7,				// Чтение из регистра 7
    	input	H0n,			// Слот обращения
    	input	BLNK,			// Картинка погашена
    	input	PA8,			// Адрес PA8
    	input	PA9,			// Адрес PA9
    	input	PA10,			// Адрес PA10
    	input	PA11,			// Адрес PA11
    	input	PA12,			// Адрес PA12
    	input	PA13,			// Адрес PA13
    	// Выходы
    	output	PWR,			// Активация записи
    	output	TSTEP,			// Счет развертки
    	output	DB_PAR,			// Данные на шину PPU
    	output	PD_RB,			// Данные в защелку
    	output	ALE,			// Сигнал ALE
    	output	PRD,			// Активация чтения
    	output	XRB,			// Данные на шину CPU
    	output	TH_MUX			// Обращение в палитру
    );
    // Переменные
    assign TH_MUX = BLNKR & PA8 & PA9 & PA10 & PA11 & PA12 & PA13;
    reg [1:0]W7Req;				// Очередь запроса записи
    reg [1:0]W7Queue;			// Очередь сигнала записи
    reg [1:0]R7Req;				// Очередь запроса чтения
    reg [1:0]R7Queue;			// Очередь сигнала чтения
    reg BLNKR;					// Регистр гашения
    // Выход записи
    assign DB_PAR = W7Queue[1] & ~W7Queue[0];
    assign PWR = TH_MUX | ~DB_PAR;
    // Выход чтения
    assign PD_RB = R7Queue[1] & ~R7Queue[0];
    assign PRD = ~(PD_RB | (H0n & ~BLNKR));
    // Выход шага счетчика растра
    assign TSTEP = DB_PAR | PD_RB;
    // Выход ALE
    assign ALE = (~W7Queue[1] & W7Queue[0]) | (~R7Queue[1] & R7Queue[0]) | (ALEGate & ~H0n & ~BLNK);
    // Данные на шину CPU
    assign XRB = R7 & ~TH_MUX;
    // Логика
    always @(posedge Clk) begin
    	// Синхронизация
    	W7Req[0] <= W7; R7Req[0] <= R7;
    	// Запросы
    	if (W7Req[0] & ~W7) W7Req[1] <= 1'b1;
    		else if (W7Queue[1]) W7Req[1] <= 1'b0;
    	if (R7Req[0] & ~R7) R7Req[1] <= 1'b1;
    		else if (R7Queue[1]) R7Req[1] <= 1'b0;
    	// Пиксельклок
    	if (PClk) begin
    		// Ротация очереди
    		W7Queue[1:0] <= {W7Queue[0],W7Req[1]};
    		R7Queue[1:0] <= {R7Queue[0],R7Req[1]};
    		// Синхронизация
    		BLNKR <= BLNK;
    		end
    end
    // конец модуля
    endmodule
    - - - Добавлено - - -

    Блок мультиплексирования шины данных PPU.

    Это маленький блок, который работает при чтении внешним CPU внутреннего состояния PPU или его локальной шины. Схемы не было, он был сразу реализован в виде комбинаторного мультиплексора.

    Я же его просто синхронизировал. Объяснять его работу, думаю, не требуется.
    Код:
    // Мультиплексор шины при чтении
    module PPU_BUS_MUX(
    	// Секция входов
    	input	Clk,			// Такты
    	input	PClk,			// Пиксельклок
    	input	PD_RB,			// Строб моста шины VRAM
    	input	XRB,			// Выбор чтения VRAM
    	input	[7:0]PAD,		// Данные VRAM
    	input	R2,				// Выбор чтения R2
    	input	[7:0]R2DB,		// Данные R2
    	input	R4,				// Выбор R4
    	input	[7:0]OB,		// Данные R4
    	input	RPIX,			// Выбор пиксельного вывода
    	input	[7:0]PIX,		// Данные пиксельного вывода
    	input	RnW,			// Выбор направления данных
    	input	nDBE,			// Строб данных
    	// Секция выходов
    	output	[7:0]Q			// Выход
    );
    // Комбинаторика
    assign Q[7:0] = (RnW & ~nDBE) ? D[7:0] : 8'hZZ;
    // Внутренние переменные
    reg [7:0]ADR;
    reg [7:0]OBR;
    reg [7:0]D;
    // Логика работы мультиплексора
    always @(posedge Clk) begin
    	// Синхронизация регистра данных обьектов (спрайтов)
    	if (PClk) OBR[7:0] <= OB[7:0];
    	// Синхронизация данных чтения VRAM
    	if (PD_RB) ADR[7:0] <= PAD[7:0];
    	// Мультиплексор
    	if (XRB) D[7:0] <= ADR[7:0];
    		else if (R2) D[7:0] <= R2DB[7:0];
    			else if (R4) D[7:0] <= OBR[7:0];
    				else if (RPIX) D[7:0] <= PIX[7:0];
    					else D[7:0] <= 8'h00;
    end
    // Конец модуля
    endmodule
    Последний раз редактировалось HardWareMan; 22.10.2017 в 10:04.

  11. #50
    Guru
    Регистрация
    08.10.2005
    Адрес
    Москва
    Сообщений
    13,550
    Спасибо Благодарностей отдано 
    1,213
    Спасибо Благодарностей получено 
    1,748
    Поблагодарили
    680 сообщений
    Mentioned
    67 Post(s)
    Tagged
    1 Thread(s)

    По умолчанию

    Несколько вопросов к @HardWareMan:

    1. Можно восстановить картинки? Все протухли.
    2. Еще не сфоткан PAL-овский чип от Dendy 6538 (2C07)?
    3. Что изменилось за 2 года?

Страница 5 из 9 ПерваяПервая 123456789 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Потактовый клон i8080 на FPGA/CPLD
    от HardWareMan в разделе Разработка электроники
    Ответов: 471
    Последнее: 06.07.2020, 19:39
  2. AY-3-8910 in FPGA
    от VELESOFT в разделе Звук
    Ответов: 18
    Последнее: 25.12.2015, 22:13
  3. ZX 48/128 FPGA
    от Александр Бухаров в разделе Несортированное железо
    Ответов: 6
    Последнее: 21.04.2015, 17:04
  4. Dendy on FPGA?
    от Ewgeny7 в разделе Nintendo
    Ответов: 29
    Последнее: 04.11.2009, 17:55
  5. Atari ST(E) на FPGA...
    от ILoveSpeccy в разделе Atari
    Ответов: 6
    Последнее: 26.08.2008, 20:55

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •