Да признаюсь - тупанул, а был так близко. :))))
https://a.radikal.ru/a02/1909/04/0b0607e9f48f.jpg
Вид для печати
Да признаюсь - тупанул, а был так близко. :))))
https://a.radikal.ru/a02/1909/04/0b0607e9f48f.jpg
Ай, красиво. Я думаю, что всем миром мы вылижем этот проект до нормального кода.
Теперь можно вытащить синхросигналы из общей каши и положить рядом со счётчиками. И оформить их в виде:
if ( counter == START ) sync <= 1'b0;
else if ( counter == END ) sync <= 1'b1;
Для hsync это будет pix_counter, а для vsync - line counter.
Ага, все шЫкарно.
Только у меня синхросигналы положительные.
Ну и вопрос :Код:if(pix_count== HSYNC_START)vga_hsync <= SYNC_ON;else if (pix_count==HSYNC_END)vga_hsync<=SYNC_OFF;
if(line_count== VSYNC_START)vga_vsync <= SYNC_ON;else if (line_count==VSYNC_END)vga_vsync<=SYNC_OFF;
Здесь OR и AND - логические или битовые?
if ( (SynRes[1] & ~SynRes[0]) | (pix_count == LINE_END) )
HardWareMan, и да , ты раннее говорил про разницу инверсий ~ и !. Можно подробней , что-то плохо ищется на верилоговских туторах, вечно какая-то хрень вылезает...
https://d.radikal.ru/d19/1909/44/ad2f9bc3d9e1.png
- - - Добавлено - - -
omercury, Свершилось, после месяца долбежа в суппорт опенкорес выслали пароль...
- - - Добавлено - - -
Что имеем на данный момент :
- - - Добавлено - - -Код:module vga_sync(
input clk_in, // Input 40 MHz clock, this is a pixel clock for this VGA mode
input reset, // Input async. active low reset signal
output reg vga_hsync, // Output horizontal sync signal
output reg vga_vsync, // Output vertical sync signal
output reg disp_enable, // Set when a writable portion of display is enabled:
output reg[9:0] pix_x, // x-coordinate of an active pixel
output reg[9:0] pix_y, // y-coordinate of an active pixel
//output reg[19:0] v_addr, // VRAM address count
output wire[7:0] data_out
);
//======================================================================
localparam SYNC_ON = 1'b1; // Define the polarity of sync pulses (psitive)
localparam SYNC_OFF = 1'b0;
localparam HSYNC_START = 840;
localparam HSYNC_END = 968;
localparam LINE_END = 1056;
localparam VSYNC_START = 601;
localparam VSYNC_END = 605;
localparam FRAME_END = 628;
localparam H_ACTIV = 800;
localparam V_ACTIV = 600;
reg [7:0] vram [0:4095]; initial $readmemh("vram.txt", vram);
reg[9:0] line_count; // Line counter, current line
reg[15:0] pix_count; // Pixel counter, current pixel
reg[19:0] v_addr; // vaddres counter
reg [1:0]SynRes;
always @( posedge clk_in )
begin
// reset
SynRes[1:0] <= {SynRes[0],reset};
// pixel count
if ( (SynRes[1] & ~SynRes[0]) | (pix_count == LINE_END) ) pix_count <= 0; else pix_count <= pix_count + 1;
// line count
if ( (SynRes[1] & ~SynRes[0]) | (line_count == FRAME_END ) ) line_count <= 0;
else if ( pix_count == LINE_END ) line_count <= line_count + 1;
// synhroimpulse
if(pix_count== HSYNC_START)vga_hsync <= SYNC_ON;else if (pix_count==HSYNC_END)vga_hsync<=SYNC_OFF;
if(line_count== VSYNC_START)vga_vsync <= SYNC_ON;else if (line_count==VSYNC_END)vga_vsync<=SYNC_OFF;
if (SynRes[1] & ~SynRes[0]) v_addr <=0;// or this: if (SynRes[1:0] == 2'b10)
else begin
// The following code defines a drawable display region and outputs
// disp_enable to 1 when within that region. Also, set the pixel coordinates
// (normalized to the top-left edge of a drawable region)
disp_enable <= 0;
pix_x <= 0;
pix_y <= 0;
if (line_count>=0 && line_count<V_ACTIV)
begin
if (pix_count>=0 && pix_count<H_ACTIV)
begin
disp_enable <= 1;
pix_x <= pix_count;
pix_y <= line_count;
v_addr <= ((pix_y*800)+pix_x);
end
end
end
end
assign data_out = vram[v_addr];
endmodule
Да и при таком раскладе оба синхроимпульса во время первой строки находятся в неопределенном состоянии .
Это все мелочи? Или вставить их инициализацию в секцию reset?
Код:if (SynRes[1] & ~SynRes[0]) begin vga_hsync <=0; vga_vsync<=0; end
И я так и не нашел - как заставить Modelsim выводить данные из vram...
https://a.radikal.ru/a35/1909/cc/472dfd542318.png
- - - Добавлено - - -
Ага, сработало, синхроимпульсы при сбросе и старте в 0...
https://a.radikal.ru/a24/1909/86/0ab80be213d2.pngКод:reg [1:0]SynRes;
always @( posedge clk_in )
begin
// reset
SynRes[1:0] <= {SynRes[0],reset};
// pixel count
if ( (SynRes[1] & ~SynRes[0]) | (pix_count == LINE_END) ) pix_count <= 0; else pix_count <= pix_count + 1;
// line count
if ( (SynRes[1] & ~SynRes[0]) | (line_count == FRAME_END ) ) line_count <= 0;
else if ( pix_count == LINE_END ) line_count <= line_count + 1;
// synhroimpulse
if (SynRes[1] & ~SynRes[0]) begin vga_hsync <=0; vga_vsync<=0; end
if(pix_count== HSYNC_START)vga_hsync <= SYNC_ON;else if (pix_count==HSYNC_END)vga_hsync<=SYNC_OFF;
if(line_count== VSYNC_START)vga_vsync <= SYNC_ON;else if (line_count==VSYNC_END)vga_vsync<=SYNC_OFF;
if (SynRes[1] & ~SynRes[0]) v_addr <=0;// or this: if (SynRes[1:0] == 2'b10)
else begin
Строго битовые. Ты же комбинаторную логическую схему строишь, а не компаратор.
~ Побитовая инверсия.
! Логическое отрицание.
https://jpegshare.net/images/c3/b1/c...117d77aed5.png
Так'с нашел как vram выводить в Modelsim, с какого-то перепугу надо файл с содержимым пихать в папку modelsim проекта.
И увидел совсем нерадужные вести , выхлоп данных с vram на один такт опаздывает с pix_count...
https://b.radikal.ru/b00/1909/7f/296dac407b80.png
Дальше - хуже.
pix_count сбрасывается при 1057
v_addr считает 798 -0-800
https://b.radikal.ru/b25/1909/6d/5a90ce2c2192.png
Ты -1 в константах забыл указать (лучше прямо в условии, обняв в скобки). Схема синхронная, т.е. она сейчас запишет то, что будет в следующем такте. А считает она от 0. Я вижу на твоем RTL 420, а не 41F.
- - - Добавлено - - -
Кто касается строк, то это интересный глюк, дай сюда последний актуальный RTL.
Картинкой?
Скрытый текст
dosikus, отлично. Тебе надо pix_x и pix_y разобрать. Насколько я понял, это просто буферизированный вывод pix_count и line_count соответственно. Это объясняет задержку на 1 такт - всё верно. Что касается значений, то тебе надо просто в глобальном месте просто сделать перенос счетчиков по окну, например вот так:
if ( pix_count < d640 ) pix_x <= pix_count; else pix_x <= 0;
if ( line_count < d480 ) pix_y <= line_count; else pix_y <= 0;
Тогда pix_x и pix_y будут сканировать 640х480 точек, обнуляясь на гашении.
То есть меняем
НаКод:disp_enable <= 0;
pix_x <= 0;
pix_y <= 0;
if (line_count>=0 && line_count<V_ACTIV)
begin
if (pix_count>=0 && pix_count<H_ACTIV)
begin
disp_enable <= 1;
pix_x <= pix_count;
pix_y <= line_count;
v_addr <= ((pix_y*800)+pix_x);
end
end
А вот куда blank тобишь disp_enable воткнуть?Код:if ( pix_count < d800 ) pix_x <= pix_count; else pix_x <= 0;
if ( line_count < d600) pix_y <= line_count; else pix_y <= 0;
v_addr <= ((pix_y*800)+pix_x);