Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20709 Discussions

integer'image(some_int) results in "Expression is not constant" error

Altera_Forum
Honored Contributor II
1,111 Views

What is the correct way to convert an always changing integer variable to a string (to be displayed on a VGA monitor)? I have a series of if statements that take care of padding (so that the resulting string is always a certain length but as soon as I change: 

 

resulting_string <= integer'image(87465); 

 

to: 

 

resulting_string <= integer'image(some_int_var); 

 

 

 

I get an "Expression is not constant" error. What is the correct way to convert an always changing integer variable (that could be any int within the integer limits) to a string?
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
439 Views

The string type is not suitable for synthesis - it doesnt really have much meaning in hardware, it would be used more for debugging in simulation. 

What are you doing with the string? do you have some driver that can covert the characters in the string to some form of pixel matrix?
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

 

--- Quote Start ---  

The string type is not suitable for synthesis - it doesnt really have much meaning in hardware, it would be used more for debugging in simulation. 

What are you doing with the string? do you have some driver that can covert the characters in the string to some form of pixel matrix? 

--- Quote End ---  

 

 

Yes, I do. I have a font ROM that I use to tell me if a pixel should be on for any given character in a string. The only step remaining is to convert ints to strings.  

 

I went at it from every direction and finally found that I had to make a giant case block to get it to work. Now I can finally display rapidly changing variables that are really helpful for debugging. It's unfortunate that the solution had to be so retarded though.. 

 

(I already have a ROM for displaying text that the resulting string is sent to.) 

 

function int_to_str(int : integer) return string is variable a : natural := 0; variable r : string(1 to 11); begin a := abs (int); case a is when 0 => r := "0 "; when 1 => r := "1 "; when 2 => r := "2 "; when 3 => r := "3 "; . . . when 1000 => r := "1000 "; when others => r := "???????????"; end case; if (int < 0) then r := '-' & r(1 to 10); end if; return r; end int_to_str;
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

Id be interested to see this rom - does it actually synthesise to a rom? with that many chars in the string, thats a massive lookup address.. 

Using a string is really a software concept and not a hardware one - hence why you have to do a massive workaround like you have found to get it working.
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

I don't see how else I would do it. The ROM isn't really a rom anymore. I converted it into the code below.  

 

 

entity char_display is generic( text_length: integer := 1; addrWidth: integer := 11; dataWidth: integer := 8 ); port( text_to_be_displayed : in string(1 to text_length) := (others => NUL); origin_x : in integer; origin_y : in integer; current_x : in integer; current_y : in integer; this_px_is_text : out boolean; this_px_is_text_bg : out boolean ); end char_display; architecture Behavioral of char_display is type rom_type is array (0 to 2**addrWidth-1) of std_logic_vector(dataWidth-1 downto 0); -- ROM definition signal ROM: rom_type := ( -- 2^11-by-8 -- NUL: code x00 "00000000", -- 0 "00000000", -- 1 "00000000", -- 2 "00000000", -- 3 "00000000", -- 4 "00000000", -- 5 "00000000", -- 6 "00000000", -- 7 "00000000", -- 8 "00000000", -- 9 "00000000", -- a "00000000", -- b "00000000", -- c "00000000", -- d "00000000", -- e "00000000", -- f -- SOH: code x01 "00000000", -- 0 "00000000", -- 1 "01111110", -- 2 ****** "10000001", -- 3 * * "10100101", -- 4 * * * * "10000001", -- 5 * * "10000001", -- 6 * * "10111101", -- 7 * **** * "10011001", -- 8 * ** * "10000001", -- 9 * * "10000001", -- a * * "01111110", -- b ****** "00000000", -- c "00000000", -- d "00000000", -- e "00000000", -- f -- STX: code x02 "00000000", -- 0 "00000000", -- 1 "01111110", -- 2 ****** "11111111", -- 3 ******** "11011011", -- 4 ** ** ** "11111111", -- 5 ******** "11111111", -- 6 ******** "11000011", -- 7 ** ** "11100111", -- 8 *** *** "11111111", -- 9 ******** "11111111", -- a ******** "01111110", -- b ****** "00000000", -- c "00000000", -- d "00000000", -- e "00000000", -- f . . . ); begin process (text_to_be_displayed, origin_x, origin_y, current_x, current_y) (variables...) begin (combinational logic...) end process; end Behavioral; 

 

It was originally this: https://github.com/madlittlemods/fp-v-ga-text 

but in my opinion it was super over-engineered. I reduced that mess down to the one entity shown above which is working great. 

 

My question is, if the way I'm doing it is so backwards, how would you describe a process that is equally code-minimal, easy to read, and efficient?
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

Usually, you would let software control something like this 

You provide the processor with a memory the size of the VGA screen. The software can do all the fancy graphics rather easily. 

Doing it in HDL is rather long winded and cumbersum, as you're finding. 

it's just easier to send data directly to a processor, rather than a VGA screen.
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

Wouldn't that be a lot more code and take a lot more time for someone other than the person who wrote it to read and understand? It is probably not as efficient either. 

 

I only need to display text, rectangles, circles and lines. I can make those fairly easily using the same techniques I have already utilized. I don't see why a soft processor is needed. The hardest part to figure out will likely end up being that retarded hack I had to use to get it to convert ints to strings.
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

I wouldnt really call it retarted, and I wouldnt really call it a hack. 

You need to understand what underlying hardware you're trying to generate, and offset that against user understanding.  

A string is just an array of chars, which is really just an array of bytes. You're using a rom to do this. 

 

In previous designs where Ive had graphics overlay, it has always come from a processor. Either 2 bits per pixel for black and white overlaikd (black, white, grey - level set by a register, and normal video) or colour at 24bit/pixel RGB. But in my case the processors were already there performing other tasks. 

I have also had a design with FPGA generated graphcis - and it ends up being long winded and overly complicated.
0 Kudos
Altera_Forum
Honored Contributor II
439 Views

I'm actually not using a ROM or RAM for any of it. There is a giant std_logic_vector that dictates which pixels should be on or off for any given character. Then, to be able view non-character variables like integers, I have that ridiculous, giant case block which is used to convert an int to a string. I had a more elegant solution that actually performed some math to figure out, digit by digit, what the string needed to be for any given int but it didn't like that for reasons I can't remember and I had to use the giant case block instead.

0 Kudos
Reply