para Loop Through String en VHDL

-2

Estoy tratando de escribir un bucle en VHDL que imprima un determinado mensaje en una pantalla LCD.

He predefinido lo siguiente:

constant LCDHP  :integer range 0 to 1056:=  1056;--horizontal period
constant LCDHPW :integer range 0 to 30  :=  30  ;--horizontal pulse-width
constant LCDHBP :integer range 0 to 16  :=  16  ;--horizontal back-porch
constant LCDHFP :integer range 0 to 210 :=  210 ;--horizontal front-porch
constant LCDVP  :integer range 0 to 525 :=  525 ;--vertical period
constant LCDVPW :integer range 0 to 13  :=  13  ;--vertical pulse-width
constant LCDVBP :integer range 0 to 10  :=  10  ;--vertical back-porch
constant LCDVFP :integer range 0 to 22  :=  22  ;--vertical front-porch
type coordinate is record
    H:integer range LCDHP'range;
    V:integer range LCDVP'range;
end record;
constant TP:coordinate:=(H=>LCDHP-LCDHFP,V=>LCDVP-LCDVFP);--text-position
function char2ascii(char:character)return std_logic_vector is
begin
    case char is
    when'0'=>return conv_std_logic_vector(16,7);
    when'1'=>return conv_std_logic_vector(17,7);
    when'2'=>return conv_std_logic_vector(18,7);
    when'3'=>return conv_std_logic_vector(19,7);
    ...
end function char2ascii;
constant message0:string(1 to 60):=   "Hello, I'm Doron Behar and I'm the developer of this project";

No entregaré todo el contenido de este archivo porque es muy largo y la mayoría no es relevante. Sin embargo, he logrado imprimir texto en la pantalla con un método diferente:

El método estándar (y simple ) es escribir un proceso asíncrono. (También podría escribirse de forma paralela sin un proceso y utilizando when else ). Mostraré un ejemplo para el método estándar:

process(pixel_row,pixel_column)
begin
    if pixel_row>TP.H - 16 and pixel_row <= TP.H then
        if pixel_column <= TP.V - 0 * 8 and pixel_column > TP.V - 1 * 8 then
            char_code <= char2ascii(message0(1));
        elsif pixel_column <= TP.V - 1 * 8 and pixel_column > TP.V - 2 * 8 then
            char_code <= char2ascii(message0(2));
        elsif pixel_column <= TP.V - 2 * 8 and pixel_column > TP.V - 3 * 8 then
            char_code <= char2ascii(message0(3));
        elsif--well you get the idea..
            char_code <= ...;
        else
            char_code <= char2ascii(' ');
        end if;
    else
        char_code <= char2ascii(' ');
    end if;
end process;

Esta no es una forma inteligente de imprimir el texto, es bueno si la cadena no es larga y funciona, pero en el caso de una oración completa no es muy eficiente porque requiere escribir 2 * mensaje de longitud (que es 120 en mi ejemplo) líneas para 1 mensaje.

La solución en la que pensé estaba usando un bucle:

process(pixel_row,pixel_column)
begin
    for i in message0 'range loop
        if pixel_row>TP.H-16 and pixel_row<=TP.H then
            if pixel_column<=TP.V-(i-1)*8 and pixel_column>TP.V-i*8 then
                char_code<=char2ascii(message0(i));
            else
                char_code<=char2ascii(' ');
            end if;
        else
            char_code<=char2ascii(' ');
        end if;
    end loop;
end process;

¡Por alguna razón, simplemente no funciona! No estoy seguro de cuál es el motivo por el que no veo nada en la pantalla mientras que puedo imprimir texto con el primer método.

También he intentado usar for generate :

txt:for i in message0'range generate
    char_code<= char2ascii(message0(i)) when
        pixel_row>TP.H-16 and pixel_row<=TP.H and pixel_column<=TP.V-(i-1)*8 and pixel_column>TP.V-i*8
    else        char2ascii(' ');
end generate txt;

Pero tengo los siguientes errores:

Error (10028): Can't resolve multiple constant drivers for net "char_code[6]" at display-control.vhd(339)
Error (10029): Constant driver at display-control.vhd(339)
Error (10028): Can't resolve multiple constant drivers for net "char_code[5]" at display-control.vhd(339)
Error (10028): Can't resolve multiple constant drivers for net "char_code[3]" at display-control.vhd(339)
Error (10028): Can't resolve multiple constant drivers for net "char_code[2]" at display-control.vhd(339)
Error (10028): Can't resolve multiple constant drivers for net "char_code[1]" at display-control.vhd(339)
Error (10028): Can't resolve multiple constant drivers for net "char_code[0]" at display-control.vhd(339)

¿Hay algún problema con la forma en que trato el rango de la cuerda? ¿Es posible hacer lo que estoy tratando de hacer o debo pensar en un método totalmente diferente?

Cualquier ayuda apreciada :)

    
pregunta Doron Behar

1 respuesta

2

No quieres un bucle aquí. Pero su proceso sí necesita generar i (el índice en el mensaje) desde TP.V , probablemente a través de la división entre 8

Algo como:

process()
   variable i : natural range 0 to LCDVP/8;
begin
    if pixel_row>TP.H - 16 and pixel_row <= TP.H then
        i := pixel_column / 8;
        if i <= message0'high then
            char_code <= char2ascii(message0(i));
        else
            char_code <= char2ascii(' ');
        end if;
    else
        char_code <= char2ascii(' ');
    end if;
end process;

Puede objetar el uso de la división en la síntesis, pero nunca he visto una herramienta de síntesis por ahí (al menos en este siglo) que no pueda realizar la optimización obvia para una división fija en 8.

Observaré que también estás haciendo la vida innecesariamente difícil para ti mismo con la declaración de char2ascii : su cuerpo debería ser prácticamente de una sola línea también.

    
respondido por el Brian Drummond

Lea otras preguntas en las etiquetas