-2
\$\begingroup\$

I'm trying to write a loop in VHDL that will print a certain message on an LCD screen.

I have predefined the following:

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";

I will not deliver all the content of this file because it's very long and most of it is not relevant. Yet, I have managed to print text on the screen with a different method:

The standard (and simple) method is to write a asynchronous process. (It could also be written in a parallel way without a process and using when else) I'll show an example for the standard method:

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;

This is not a smart way to print the text, it's good if the string is not long and it's working but in the case of a full sentence it's not very efficient because it requires to write 2*message'length (which is 120 in my example) lines for 1 message.

The solution I thought of was using a loop:

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;

From some reason it just doesn't work! I'm not sure what is the reason why I see nothing on the screen while I can print text with the 1st method.

I've also tried using 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;

But I got the following errors:

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)

Is there something wrong with the way I treat the string's range? Is it even possible to do what I'm trying to do or should I think of a totally different method?

Any Help Appreciated :)

\$\endgroup\$
  • 1
    \$\begingroup\$ You are saying your design is working, but how? Processes without sensitivity lists are not allowed in synthesis and driving a LC-Display bus without a clock won't work either... \$\endgroup\$ – Paebbels Feb 7 '16 at 18:00
  • \$\begingroup\$ you are right @Paebbels, I've made an edit. I dropped off the sensitivity list originally in order to spare some of the content from the post. \$\endgroup\$ – Doron Behar Feb 8 '16 at 16:35
2
\$\begingroup\$

You don't want a loop here. But your process does need to generate i (the index into the message) from TP.V, probably through division by 8.

Something like:

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;

You may object to the use of division in synthesis, but I've never seen a synthesis tool out there (this century at least) that can't make the obvious optimisation for a fixed division by 8.

I'll note the you are also making life unnecessarily hard for yourself with the declaration of char2ascii : its body should be pretty much a one-liner too.

\$\endgroup\$
  • \$\begingroup\$ TP.V is constant. It doesn't make sense to write i:=TP.V/8 because it's just gonna make i equal to a certain number and that's it. \$\endgroup\$ – Doron Behar Feb 7 '16 at 17:49
  • \$\begingroup\$ Details, details.... (Edited) \$\endgroup\$ – Brian Drummond Feb 7 '16 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.