Aprendiendo Verilog con el ZXUno (salida monocromo)

Diseño HDL con este lenguaje. Módulos y testbenchs. Estilos y trucos de codificación, etc. NOTA: dado que hay entornos como ISE que soportan Verilog pero no SystemVerilog, señalad dentro de un post que de lo que se va a tratar es SystemVerilog si es el caso.
Responder
Avatar de Usuario
spark2k06
PLA
Mensajes: 49
Registrado: 17 Ago 2018, 18:43

Aprendiendo Verilog con el ZXUno (salida monocromo)

Mensaje por spark2k06 » 23 May 2021, 10:47

Hola,

Como parte de mi fase de aprendizaje programando FPGAs, he llevado a cabo una modificación en el core de Spectrum para permitir la selección de diferentes salidas de video monocromáticas, característica que siempre me ha gustado porque proporciona otra experiencia retro y puede traer recuerdos con monitores CRT monocromáticos antiguos:

Imagen

Las opciones disponibles son verde, ámbar y blanco y negro, aparte de color, que sería la salida de vídeo por defecto al arrancar el core, y se intercambia de uno a otro con la tecla END. Para llevar a cabo la implementación, he estudiado el módulo que desarrolló @mcleod_ideafix en el core de Amstrad CPC para salida monocromática verde, fuentes que muy generosamente me ha facilitado en privado, y del cual he aprendido mucho, gracias!.

Dadas las limitaciones que se nos presenta en el zxuno original, con 3 bits de profundidad por color de RGB, no es posible más que ofrecer 7 intensidades de un color diferentes. Esto plantea un verdadero reto en la representación gráfica de sistemas cuya paleta de colores es mayor, en los cuales dicha carencia puede ser más o menos fácil disimular.

Concretamente en el Spectrum, sin entrar en modos especiales como el ULA plus, disponemos de la siguiente paleta de colores:

Imagen

15 colores contando el color negro, y de los cuales, la mitad son los mismos pero de mayor intensidad. Además en la imagen se muestran ordenados de menor a mayor luminancia. El cálculo de la luminancia se obtiene a partir de una simple formula que pondera los valores de RGB:

0.2126*R + 0.7152*G + 0.0722*B

Con tan pocos niveles de intensidad disponibles, no merece la pena, ni creo que sea posible implementar este cálculo. Por ese motivo, la mejor opción es hacer una conversión directa según su luminancia. He optado por no hacer distinción entre un mismo color y su correspondiente de mayor intensidad, entre otras cosas porque no se pueden representar por la limitación comentada, y representar paletas como la del ULA plus es impensable. Los fuentes los he dejado disponibles en el siguiente repositorio de mi cuenta de GitHub.

He pensado que, tal vez, de alguna forma ingeniosa mediante la implementación de un framebuffer, sea posible crear algún tipo de efecto intercambiando rápidamente diferentes tipos de colores que pueda engañar al ojo humano... es una opción que podría ser interesante investigar, aunque de haberlo, este tipo de efectos podrían tener más sentido en monitores CRT, dudo mucho que en TFT/LCD tengan efecto.

Si alguien está interesado en el mismo, puede obtenerlo directamente del repositorio de GitHub facilitado.

Avatar de Usuario
mcleod_ideafix
Site Admin
Mensajes: 80
Registrado: 14 Ago 2018, 01:15

Re: Aprendiendo Verilog con el ZXUno (salida monocromo)

Mensaje por mcleod_ideafix » 07 Dic 2021, 11:22

En la Spartan 6 hay unos cuantos multiplicadores ociosos, sin hacer nada (sólo uso uno en el core), así que puedes usarlos para hacer multiplicaciones para implementar el cálculo del nivel de gris. De esa forma, y aunque el DAC de 3 bits es lo que es, puedes acomodar no solamente la paleta original del Spectrum sino también la de ULAplus.

Quedaría así:

Código: Seleccionar todo

module monochrome (
  input wire [1:0] monochrome_selection,
  input wire [2:0] ri,
  input wire [2:0] gi,
  input wire [2:0] bi,
  output reg [2:0] ro,
  output reg [2:0] go,
  output reg [2:0] bo
  );

  reg [10:0] grey_value;
  reg [2:0] monochrome_scale_spectrum;

  always @* begin
    ro = ri;
    go = gi;
    bo = bi;

    // 0.2126*R + 0.7152*G + 0.0722*B equivalente a (54*R + 183*G + 18*B)/256
    grey_value = 8'd54*ri + 8'd183*gi + 8'd18*bi;  // calculo del nivel de gris en 11 bits
    monochrome_scale_spectrum = grey_value[10:8] + grey_value[7];  // dividimos entre 256 redondeando al entero mas proximo

    if (monochrome_selection == 3'b01) begin // Verde
      ro = 3'b000;
      go = monochrome_scale_spectrum;
      bo = 3'b000;
    end
    else if (monochrome_selection == 3'b10) begin // Ambar
      ro = monochrome_scale_spectrum;
      go = {1'b0, monochrome_scale_spectrum[2:1]};
      bo = 3'b000;
    end
    else if (monochrome_selection == 3'b11) begin // Blanco y negro
      ro = monochrome_scale_spectrum;
      go = monochrome_scale_spectrum;
      bo = monochrome_scale_spectrum;
    end
  end
endmodule
Una opción que no use multiplicadores, puede usar una LUT de 512 entradas, pero te puedes encontrar con que use muchos recursos, al ser una LUT asíncrona. Quedaría así:

Código: Seleccionar todo

module monochrome (
  input wire [1:0] monochrome_selection,
  input wire [2:0] ri,
  input wire [2:0] gi,
  input wire [2:0] bi,
  output reg [2:0] ro,
  output reg [2:0] go,
  output reg [2:0] bo
  );

  reg [10:0] grey_value;
  reg [2:0] monochrome_scale_spectrum;

  reg [2:0] lut[0:511];
  initial begin
    lut[  0] = 3'd0;
    lut[  1] = 3'd0;
    lut[  2] = 3'd0;
    lut[  3] = 3'd0;
    lut[  4] = 3'd0;
    lut[  5] = 3'd0;
    lut[  6] = 3'd0;
    lut[  7] = 3'd0;
    lut[  8] = 3'd1;
    lut[  9] = 3'd1;
    lut[ 10] = 3'd1;
    lut[ 11] = 3'd1;
    lut[ 12] = 3'd1;
    lut[ 13] = 3'd1;
    lut[ 14] = 3'd1;
    lut[ 15] = 3'd1;
    lut[ 16] = 3'd1;
    lut[ 17] = 3'd2;
    lut[ 18] = 3'd2;
    lut[ 19] = 3'd2;
    lut[ 20] = 3'd2;
    lut[ 21] = 3'd2;
    lut[ 22] = 3'd2;
    lut[ 23] = 3'd2;
    lut[ 24] = 3'd2;
    lut[ 25] = 3'd2;
    lut[ 26] = 3'd2;
    lut[ 27] = 3'd2;
    lut[ 28] = 3'd2;
    lut[ 29] = 3'd3;
    lut[ 30] = 3'd3;
    lut[ 31] = 3'd3;
    lut[ 32] = 3'd3;
    lut[ 33] = 3'd3;
    lut[ 34] = 3'd3;
    lut[ 35] = 3'd3;
    lut[ 36] = 3'd3;
    lut[ 37] = 3'd3;
    lut[ 38] = 3'd3;
    lut[ 39] = 3'd3;
    lut[ 40] = 3'd4;
    lut[ 41] = 3'd4;
    lut[ 42] = 3'd4;
    lut[ 43] = 3'd4;
    lut[ 44] = 3'd4;
    lut[ 45] = 3'd4;
    lut[ 46] = 3'd4;
    lut[ 47] = 3'd4;
    lut[ 48] = 3'd4;
    lut[ 49] = 3'd4;
    lut[ 50] = 3'd4;
    lut[ 51] = 3'd5;
    lut[ 52] = 3'd5;
    lut[ 53] = 3'd5;
    lut[ 54] = 3'd5;
    lut[ 55] = 3'd5;
    lut[ 56] = 3'd5;
    lut[ 57] = 3'd5;
    lut[ 58] = 3'd5;
    lut[ 59] = 3'd5;
    lut[ 60] = 3'd5;
    lut[ 61] = 3'd5;
    lut[ 62] = 3'd5;
    lut[ 63] = 3'd6;
    lut[ 64] = 3'd0;
    lut[ 65] = 3'd0;
    lut[ 66] = 3'd0;
    lut[ 67] = 3'd0;
    lut[ 68] = 3'd0;
    lut[ 69] = 3'd1;
    lut[ 70] = 3'd1;
    lut[ 71] = 3'd1;
    lut[ 72] = 3'd1;
    lut[ 73] = 3'd1;
    lut[ 74] = 3'd1;
    lut[ 75] = 3'd1;
    lut[ 76] = 3'd1;
    lut[ 77] = 3'd1;
    lut[ 78] = 3'd1;
    lut[ 79] = 3'd1;
    lut[ 80] = 3'd2;
    lut[ 81] = 3'd2;
    lut[ 82] = 3'd2;
    lut[ 83] = 3'd2;
    lut[ 84] = 3'd2;
    lut[ 85] = 3'd2;
    lut[ 86] = 3'd2;
    lut[ 87] = 3'd2;
    lut[ 88] = 3'd2;
    lut[ 89] = 3'd2;
    lut[ 90] = 3'd3;
    lut[ 91] = 3'd3;
    lut[ 92] = 3'd3;
    lut[ 93] = 3'd3;
    lut[ 94] = 3'd3;
    lut[ 95] = 3'd3;
    lut[ 96] = 3'd3;
    lut[ 97] = 3'd3;
    lut[ 98] = 3'd3;
    lut[ 99] = 3'd3;
    lut[100] = 3'd3;
    lut[101] = 3'd3;
    lut[102] = 3'd4;
    lut[103] = 3'd4;
    lut[104] = 3'd4;
    lut[105] = 3'd4;
    lut[106] = 3'd4;
    lut[107] = 3'd4;
    lut[108] = 3'd4;
    lut[109] = 3'd4;
    lut[110] = 3'd4;
    lut[111] = 3'd4;
    lut[112] = 3'd5;
    lut[113] = 3'd5;
    lut[114] = 3'd5;
    lut[115] = 3'd5;
    lut[116] = 3'd5;
    lut[117] = 3'd5;
    lut[118] = 3'd5;
    lut[119] = 3'd5;
    lut[120] = 3'd5;
    lut[121] = 3'd5;
    lut[122] = 3'd5;
    lut[123] = 3'd5;
    lut[124] = 3'd6;
    lut[125] = 3'd6;
    lut[126] = 3'd6;
    lut[127] = 3'd6;
    lut[128] = 3'd0;
    lut[129] = 3'd0;
    lut[130] = 3'd1;
    lut[131] = 3'd1;
    lut[132] = 3'd1;
    lut[133] = 3'd1;
    lut[134] = 3'd1;
    lut[135] = 3'd1;
    lut[136] = 3'd1;
    lut[137] = 3'd1;
    lut[138] = 3'd1;
    lut[139] = 3'd1;
    lut[140] = 3'd1;
    lut[141] = 3'd1;
    lut[142] = 3'd2;
    lut[143] = 3'd2;
    lut[144] = 3'd2;
    lut[145] = 3'd2;
    lut[146] = 3'd2;
    lut[147] = 3'd2;
    lut[148] = 3'd2;
    lut[149] = 3'd2;
    lut[150] = 3'd2;
    lut[151] = 3'd2;
    lut[152] = 3'd3;
    lut[153] = 3'd3;
    lut[154] = 3'd3;
    lut[155] = 3'd3;
    lut[156] = 3'd3;
    lut[157] = 3'd3;
    lut[158] = 3'd3;
    lut[159] = 3'd3;
    lut[160] = 3'd3;
    lut[161] = 3'd3;
    lut[162] = 3'd3;
    lut[163] = 3'd4;
    lut[164] = 3'd4;
    lut[165] = 3'd4;
    lut[166] = 3'd4;
    lut[167] = 3'd4;
    lut[168] = 3'd4;
    lut[169] = 3'd4;
    lut[170] = 3'd4;
    lut[171] = 3'd4;
    lut[172] = 3'd4;
    lut[173] = 3'd4;
    lut[174] = 3'd4;
    lut[175] = 3'd5;
    lut[176] = 3'd5;
    lut[177] = 3'd5;
    lut[178] = 3'd5;
    lut[179] = 3'd5;
    lut[180] = 3'd5;
    lut[181] = 3'd5;
    lut[182] = 3'd5;
    lut[183] = 3'd5;
    lut[184] = 3'd5;
    lut[185] = 3'd6;
    lut[186] = 3'd6;
    lut[187] = 3'd6;
    lut[188] = 3'd6;
    lut[189] = 3'd6;
    lut[190] = 3'd6;
    lut[191] = 3'd6;
    lut[192] = 3'd1;
    lut[193] = 3'd1;
    lut[194] = 3'd1;
    lut[195] = 3'd1;
    lut[196] = 3'd1;
    lut[197] = 3'd1;
    lut[198] = 3'd1;
    lut[199] = 3'd1;
    lut[200] = 3'd1;
    lut[201] = 3'd1;
    lut[202] = 3'd1;
    lut[203] = 3'd2;
    lut[204] = 3'd2;
    lut[205] = 3'd2;
    lut[206] = 3'd2;
    lut[207] = 3'd2;
    lut[208] = 3'd2;
    lut[209] = 3'd2;
    lut[210] = 3'd2;
    lut[211] = 3'd2;
    lut[212] = 3'd2;
    lut[213] = 3'd2;
    lut[214] = 3'd2;
    lut[215] = 3'd3;
    lut[216] = 3'd3;
    lut[217] = 3'd3;
    lut[218] = 3'd3;
    lut[219] = 3'd3;
    lut[220] = 3'd3;
    lut[221] = 3'd3;
    lut[222] = 3'd3;
    lut[223] = 3'd3;
    lut[224] = 3'd4;
    lut[225] = 3'd4;
    lut[226] = 3'd4;
    lut[227] = 3'd4;
    lut[228] = 3'd4;
    lut[229] = 3'd4;
    lut[230] = 3'd4;
    lut[231] = 3'd4;
    lut[232] = 3'd4;
    lut[233] = 3'd4;
    lut[234] = 3'd4;
    lut[235] = 3'd4;
    lut[236] = 3'd5;
    lut[237] = 3'd5;
    lut[238] = 3'd5;
    lut[239] = 3'd5;
    lut[240] = 3'd5;
    lut[241] = 3'd5;
    lut[242] = 3'd5;
    lut[243] = 3'd5;
    lut[244] = 3'd5;
    lut[245] = 3'd5;
    lut[246] = 3'd5;
    lut[247] = 3'd5;
    lut[248] = 3'd6;
    lut[249] = 3'd6;
    lut[250] = 3'd6;
    lut[251] = 3'd6;
    lut[252] = 3'd6;
    lut[253] = 3'd6;
    lut[254] = 3'd6;
    lut[255] = 3'd6;
    lut[256] = 3'd1;
    lut[257] = 3'd1;
    lut[258] = 3'd1;
    lut[259] = 3'd1;
    lut[260] = 3'd1;
    lut[261] = 3'd1;
    lut[262] = 3'd1;
    lut[263] = 3'd1;
    lut[264] = 3'd2;
    lut[265] = 3'd2;
    lut[266] = 3'd2;
    lut[267] = 3'd2;
    lut[268] = 3'd2;
    lut[269] = 3'd2;
    lut[270] = 3'd2;
    lut[271] = 3'd2;
    lut[272] = 3'd2;
    lut[273] = 3'd2;
    lut[274] = 3'd2;
    lut[275] = 3'd2;
    lut[276] = 3'd3;
    lut[277] = 3'd3;
    lut[278] = 3'd3;
    lut[279] = 3'd3;
    lut[280] = 3'd3;
    lut[281] = 3'd3;
    lut[282] = 3'd3;
    lut[283] = 3'd3;
    lut[284] = 3'd3;
    lut[285] = 3'd3;
    lut[286] = 3'd3;
    lut[287] = 3'd3;
    lut[288] = 3'd4;
    lut[289] = 3'd4;
    lut[290] = 3'd4;
    lut[291] = 3'd4;
    lut[292] = 3'd4;
    lut[293] = 3'd4;
    lut[294] = 3'd4;
    lut[295] = 3'd4;
    lut[296] = 3'd4;
    lut[297] = 3'd5;
    lut[298] = 3'd5;
    lut[299] = 3'd5;
    lut[300] = 3'd5;
    lut[301] = 3'd5;
    lut[302] = 3'd5;
    lut[303] = 3'd5;
    lut[304] = 3'd5;
    lut[305] = 3'd5;
    lut[306] = 3'd5;
    lut[307] = 3'd5;
    lut[308] = 3'd5;
    lut[309] = 3'd6;
    lut[310] = 3'd6;
    lut[311] = 3'd6;
    lut[312] = 3'd6;
    lut[313] = 3'd6;
    lut[314] = 3'd6;
    lut[315] = 3'd6;
    lut[316] = 3'd6;
    lut[317] = 3'd6;
    lut[318] = 3'd6;
    lut[319] = 3'd6;
    lut[320] = 3'd1;
    lut[321] = 3'd1;
    lut[322] = 3'd1;
    lut[323] = 3'd1;
    lut[324] = 3'd1;
    lut[325] = 3'd1;
    lut[326] = 3'd1;
    lut[327] = 3'd2;
    lut[328] = 3'd2;
    lut[329] = 3'd2;
    lut[330] = 3'd2;
    lut[331] = 3'd2;
    lut[332] = 3'd2;
    lut[333] = 3'd2;
    lut[334] = 3'd2;
    lut[335] = 3'd2;
    lut[336] = 3'd2;
    lut[337] = 3'd3;
    lut[338] = 3'd3;
    lut[339] = 3'd3;
    lut[340] = 3'd3;
    lut[341] = 3'd3;
    lut[342] = 3'd3;
    lut[343] = 3'd3;
    lut[344] = 3'd3;
    lut[345] = 3'd3;
    lut[346] = 3'd3;
    lut[347] = 3'd3;
    lut[348] = 3'd3;
    lut[349] = 3'd4;
    lut[350] = 3'd4;
    lut[351] = 3'd4;
    lut[352] = 3'd4;
    lut[353] = 3'd4;
    lut[354] = 3'd4;
    lut[355] = 3'd4;
    lut[356] = 3'd4;
    lut[357] = 3'd4;
    lut[358] = 3'd4;
    lut[359] = 3'd4;
    lut[360] = 3'd5;
    lut[361] = 3'd5;
    lut[362] = 3'd5;
    lut[363] = 3'd5;
    lut[364] = 3'd5;
    lut[365] = 3'd5;
    lut[366] = 3'd5;
    lut[367] = 3'd5;
    lut[368] = 3'd5;
    lut[369] = 3'd5;
    lut[370] = 3'd6;
    lut[371] = 3'd6;
    lut[372] = 3'd6;
    lut[373] = 3'd6;
    lut[374] = 3'd6;
    lut[375] = 3'd6;
    lut[376] = 3'd6;
    lut[377] = 3'd6;
    lut[378] = 3'd6;
    lut[379] = 3'd6;
    lut[380] = 3'd6;
    lut[381] = 3'd6;
    lut[382] = 3'd7;
    lut[383] = 3'd7;
    lut[384] = 3'd1;
    lut[385] = 3'd1;
    lut[386] = 3'd1;
    lut[387] = 3'd1;
    lut[388] = 3'd2;
    lut[389] = 3'd2;
    lut[390] = 3'd2;
    lut[391] = 3'd2;
    lut[392] = 3'd2;
    lut[393] = 3'd2;
    lut[394] = 3'd2;
    lut[395] = 3'd2;
    lut[396] = 3'd2;
    lut[397] = 3'd2;
    lut[398] = 3'd2;
    lut[399] = 3'd2;
    lut[400] = 3'd3;
    lut[401] = 3'd3;
    lut[402] = 3'd3;
    lut[403] = 3'd3;
    lut[404] = 3'd3;
    lut[405] = 3'd3;
    lut[406] = 3'd3;
    lut[407] = 3'd3;
    lut[408] = 3'd3;
    lut[409] = 3'd3;
    lut[410] = 3'd4;
    lut[411] = 3'd4;
    lut[412] = 3'd4;
    lut[413] = 3'd4;
    lut[414] = 3'd4;
    lut[415] = 3'd4;
    lut[416] = 3'd4;
    lut[417] = 3'd4;
    lut[418] = 3'd4;
    lut[419] = 3'd4;
    lut[420] = 3'd4;
    lut[421] = 3'd4;
    lut[422] = 3'd5;
    lut[423] = 3'd5;
    lut[424] = 3'd5;
    lut[425] = 3'd5;
    lut[426] = 3'd5;
    lut[427] = 3'd5;
    lut[428] = 3'd5;
    lut[429] = 3'd5;
    lut[430] = 3'd5;
    lut[431] = 3'd5;
    lut[432] = 3'd6;
    lut[433] = 3'd6;
    lut[434] = 3'd6;
    lut[435] = 3'd6;
    lut[436] = 3'd6;
    lut[437] = 3'd6;
    lut[438] = 3'd6;
    lut[439] = 3'd6;
    lut[440] = 3'd6;
    lut[441] = 3'd6;
    lut[442] = 3'd6;
    lut[443] = 3'd7;
    lut[444] = 3'd7;
    lut[445] = 3'd7;
    lut[446] = 3'd7;
    lut[447] = 3'd7;
    lut[448] = 3'd1;
    lut[449] = 3'd2;
    lut[450] = 3'd2;
    lut[451] = 3'd2;
    lut[452] = 3'd2;
    lut[453] = 3'd2;
    lut[454] = 3'd2;
    lut[455] = 3'd2;
    lut[456] = 3'd2;
    lut[457] = 3'd2;
    lut[458] = 3'd2;
    lut[459] = 3'd2;
    lut[460] = 3'd2;
    lut[461] = 3'd3;
    lut[462] = 3'd3;
    lut[463] = 3'd3;
    lut[464] = 3'd3;
    lut[465] = 3'd3;
    lut[466] = 3'd3;
    lut[467] = 3'd3;
    lut[468] = 3'd3;
    lut[469] = 3'd3;
    lut[470] = 3'd3;
    lut[471] = 3'd3;
    lut[472] = 3'd4;
    lut[473] = 3'd4;
    lut[474] = 3'd4;
    lut[475] = 3'd4;
    lut[476] = 3'd4;
    lut[477] = 3'd4;
    lut[478] = 3'd4;
    lut[479] = 3'd4;
    lut[480] = 3'd4;
    lut[481] = 3'd4;
    lut[482] = 3'd4;
    lut[483] = 3'd5;
    lut[484] = 3'd5;
    lut[485] = 3'd5;
    lut[486] = 3'd5;
    lut[487] = 3'd5;
    lut[488] = 3'd5;
    lut[489] = 3'd5;
    lut[490] = 3'd5;
    lut[491] = 3'd5;
    lut[492] = 3'd5;
    lut[493] = 3'd5;
    lut[494] = 3'd5;
    lut[495] = 3'd6;
    lut[496] = 3'd6;
    lut[497] = 3'd6;
    lut[498] = 3'd6;
    lut[499] = 3'd6;
    lut[500] = 3'd6;
    lut[501] = 3'd6;
    lut[502] = 3'd6;
    lut[503] = 3'd6;
    lut[504] = 3'd7;
    lut[505] = 3'd7;
    lut[506] = 3'd7;
    lut[507] = 3'd7;
    lut[508] = 3'd7;
    lut[509] = 3'd7;
    lut[510] = 3'd7;
    lut[511] = 3'd7;
  end

  always @* begin
    ro = ri;
    go = gi;
    bo = bi;

    // 0.2126*R + 0.7152*G + 0.0722*B equivalente a (54*R + 183*G + 18*B)/256
    monochrome_scale_spectrum = lut[{ri,gi,bi}]

    if (monochrome_selection == 3'b01) begin // Verde
      ro = 3'b000;
      go = monochrome_scale_spectrum;
      bo = 3'b000;
    end
    else if (monochrome_selection == 3'b10) begin // Ambar
      ro = monochrome_scale_spectrum;
      go = {1'b0, monochrome_scale_spectrum[2:1]};
      bo = 3'b000;
    end
    else if (monochrome_selection == 3'b11) begin // Blanco y negro
      ro = monochrome_scale_spectrum;
      go = monochrome_scale_spectrum;
      bo = monochrome_scale_spectrum;
    end
  end
endmodule
Probablemente esta segunda solución funcione mejor con un proceso secuencial, en lugar de combinacional (always @posedge... en lugar de always @* )

Avatar de Usuario
spark2k06
PLA
Mensajes: 49
Registrado: 17 Ago 2018, 18:43

Re: Aprendiendo Verilog con el ZXUno (salida monocromo)

Mensaje por spark2k06 » 08 Dic 2021, 08:29

Interesante. Sobre la opción de usar LUT de 512 entradas... otra solución podría ser como la que he utilizado para la versión de 6 bits en el core de PCXT, pero adaptada a 3 bits... con reg[2:0] component_weight[0:7]:

Código: Seleccionar todo

	reg [5:0]red_weight[0:63] = { // 0.2126*R
	6'h00, 6'h01, 6'h01, 6'h01, 6'h01, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h04,
	6'h04, 6'h04, 6'h04, 6'h05, 6'h05, 6'h05, 6'h05, 6'h05, 6'h06, 6'h06, 6'h06, 6'h06, 6'h06, 6'h07, 6'h07, 6'h07,
	6'h07, 6'h08, 6'h08, 6'h08, 6'h08, 6'h08, 6'h09, 6'h09, 6'h09, 6'h09, 6'h09, 6'h0a, 6'h0a, 6'h0a, 6'h0a, 6'h0a,
	6'h0b, 6'h0b, 6'h0b, 6'h0b, 6'h0c, 6'h0c, 6'h0c, 6'h0c, 6'h0c, 6'h0d, 6'h0d, 6'h0d, 6'h0d, 6'h0d, 6'h0e, 6'h0e
	};
	
	reg [5:0]green_weight[0:63] = { // 0.7152*G
	6'h00, 6'h01, 6'h02, 6'h03, 6'h03, 6'h04, 6'h05, 6'h06, 6'h06, 6'h07, 6'h08, 6'h08, 6'h09, 6'h0a, 6'h0b, 6'h0b,
	6'h0c, 6'h0d, 6'h0d, 6'h0e, 6'h0f, 6'h10, 6'h10, 6'h11, 6'h12, 6'h12, 6'h13, 6'h14, 6'h15, 6'h15, 6'h16, 6'h17,
	6'h17, 6'h18, 6'h19, 6'h1a, 6'h1a, 6'h1b, 6'h1c, 6'h1c, 6'h1d, 6'h1e, 6'h1f, 6'h1f, 6'h20, 6'h21, 6'h21, 6'h22,
	6'h23, 6'h24, 6'h24, 6'h25, 6'h26, 6'h26, 6'h27, 6'h28, 6'h29, 6'h29, 6'h2a, 6'h2a, 6'h2a, 6'h2b, 6'h2b, 6'h2b
	};
	
	reg [5:0]blue_weight[0:63] = { // 0.0722*B
	6'h00, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h01, 6'h02, 6'h02,
	6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h02, 6'h03, 6'h03, 6'h03, 6'h03,
	6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h03, 6'h04, 6'h04, 6'h04, 6'h04, 6'h04, 6'h04,
	6'h04, 6'h04, 6'h04, 6'h04, 6'h04, 6'h04, 6'h04, 6'h04, 6'h05, 6'h05, 6'h05, 6'h05, 6'h05, 6'h05, 6'h05, 6'h05
	};
	
		always @ (monochrome_switcher, r, g, b) begin
		case(monochrome_switcher)
			// Verde
			2'b01	: begin
				raux = 6'b0;
				gaux = red_weight[r] + green_weight[g] + blue_weight[b];				
				baux = 6'b0;
			end
			// Ambar
			2'b10	: begin
				raux = red_weight[r] + green_weight[g] + blue_weight[b];
				gaux = (red_weight[r] + green_weight[g] + blue_weight[b]) >> 1;
				baux = 6'b0;
			end
			// Blanco y negro
			2'b11	: begin
				raux = red_weight[r] + green_weight[g] + blue_weight[b];
				gaux = red_weight[r] + green_weight[g] + blue_weight[b];
				baux = red_weight[r] + green_weight[g] + blue_weight[b];
			end
			// Color
			default: begin
				raux = r;
				gaux = g;
				baux = b;
			end
		endcase
	end
	
	assign VGA_R = raux;
	assign VGA_G = gaux;
	assign VGA_B = baux;
	
Es decir, precalcular la luminancia de cada componente RGB y en el always simplemente llevar a cabo la suma. Pero sea como sea, la limitación de 3 bits es muy importante. De manera que en estos casos, una paleta adaptada a las características de vídeo de la máquina implementada creo que sigue siendo la mejor solución.

Por otro lado, con 3 bits, cualquier intento de representar una paleta como la ULAPlus es inútil, solo tenemos disponibles 7 tonalidades y eso no va a cambiar, a no ser que, como digo, hagamos algún tipo de truco visual.

Responder

Volver a “Verilog / SystemVerilog”