0
votes

Here is my dilemma:

I'm very new to programming in VHDL, and I'm currently working on an independent study project for a university class. I've made some descent headway, but I've run into an issue I haven't been able to solve.

What I'm trying to do is to display a "register" (or registers) on an LCD monitor and have it update periodically. For the time being, these values will always be integer numbers.

I have code written which displays numbers properly on the screen if that value is passed as a variable that is never altered or as a hard-coded value. However, I want to update a variable by adding to it, then pass that to my function and display it.

Essentially what I'm trying to do is this:

Every 'x' clock ticks, increment a register's value, pass that to my update_screen function which returns a new screen, and then display that further below. However, once I increment or change through reassignment (doesn't seem to matter if it is variable or a signal), all I see is '0' on the screen.

So... The following code properly updates my display unless I uncomment the commented lines. At that point, it just shows '0'.

--currentRegVal := currentRegVal + 1;
--screenVal <= 25;

-- screen holds the values for the current screen
-- The second argument is the row on the screen to be updated
-- The third argument is the value to display there
screen := update_screen(screen, 1, currentRegVal);
screen := update_screen(screen, 0, screenVal + 25);

The problem seems to be stemming from the integer'image attribute (or more accurately, my understanding of it). When I pass in a hardcoded value or a variable that hasn't been altered, it returns what I expect. However, as soon as I modified the variable/signal in ANY way it seems to return the string "0".

Below is my update_screen function:

function update_screen(screen: screenData; reg, regVal: integer) return screenData is
    -- A function may declare local variables. These do not retain their values between successive calls,
   -- but are re-initialised each time. Array-type parameters may be unconstrained:
    constant screenWidth: integer := screen'length(2);
    constant strRegVal: string := integer'image(regVal);
    constant strRegLen: integer := strRegVal'length;

    variable newScreen: screenData := screen;
begin
    for dex in 1 to screenWidth loop
        if dex <= strRegLen then
            newScreen(reg, dex-1) := strRegVal(dex);

        else
            newScreen(reg, dex-1) := ' ';
        end if;

        -- The next two ifs were my attempt to figure out what
        -- was going on... 

        --The value itself never seems to be 0... the screen is not all 5's
        if regVal = 0 then
            newScreen := (others => (others => '5'));
        end if;

        -- But the string value is "0" if the variable/signal is ever modified...
        -- 'd' shows up in the designated row.
        if strRegVal = "0" then
            newScreen(reg*3, 1) := 'd';
        end if;
    end loop;
    return newScreen;
end update_screen;

A couple important points (added 2011-07-26):

  • I'm using the Quartus II free (web) edition to design/compile my project.
  • The code which is updating the variables is in a process.
  • At the time of the original posting, the only steps I had taken were to compile my code and program an Altera DE2 FPGA board with the result (I wasn't sure how to perform any kind of simulations).

Thanks in advance for any help and advice. Also, as I said, I'm new to VHDL programming, so if there is a much better way to do something I'm doing here, please let me know. I would also greatly appreciate useful links to any resources about the language itself.

Update (2011-07-26):

I downloaded GHDL as Martin Thompson suggested, but I have not actually used it yet because I'm not sure how to go about doing so with my current Quartus II project (or if I even can). I'll have to do some reading before it is useful to me. However, yesterday I managed to install ModelSim-Altera which works directly with Quartus II and allowed me to perform some simulation.

I did my best to set up some waveforms that would allow me to test, and I was at least able to examine the execution of the code which I believed to be failing. However, during simulation, I've verified in multiple ways that the "screen" object does contain the value I want it to contain after the *screen_update* function runs. When running on the Altera DE2, however, it still fails.

  • Note: I did verify that the screen actually does update by directly setting the value of a particular element on the screen to different values depending on whether or not the currentRegVal is even or odd.

I'll plan on posting some code tomorrow, but for now:

What reasons are there that simulation would provide different results? My guess is something to due with timing, but it is really just a guess. If I am correct, how can I go about trying to resolve the issue?

2
More information which might help us: What VHDL compiler are you using? Is the problem in simulation or synthesis? If in synthesis, does it work OK in simulation? Is the update code (first block) you are using in a process or not? - Martin Thompson
I'm using the Quartus II free (web) edition to design/compile my project. The code which is updating the variables is in a process, but we already discussed that a little in the comments below. Currently the only thing I've done is compile my code and program an ALtera DE2 FPGA board through the Quartus II software (no simulation... I'm not sure how to at the moment, so I guess I'll look into that). Currently I do not have any simulation waveforms, so I'll see what I can do to create some. In the mean time... any other ideas? - Myles
Thanks for the updates - please could you include them in the body of your question, and just post a small comment saying you've done so, rather than "conversing" in the comments. Simulation is your friend - download GHDL and see if it behaves the same. If you can post a complete (minimal - not your whole codebase!) sample bit of code that fails, state what should happen and what really happens, others may be able to compile it on their tools and see different behaviour, or debug it for you. I stress, small sample code :) - Martin Thompson
I added some updates to my original post, please let me know if you have any feedback for me. For now, it doesn't include code because I need to get to bed, but I'll try to post some tomorrow if what I just posted doesn't get us anywhere. - Myles

2 Answers

0
votes

I guess the problem is related to the fact that you declared strRegVal as a constant. I think it should better be a variable, e.g. something like this might work:

function update_screen(screen: screenData; reg, regVal: integer) return screenData is
  ...
  variable strRegVal: string;
  variable strRegLen: integer;
  ...
begin
  strRegVal := integer'image(regVal);
  strRegLen := strRegVal'length;
  ...
end update_screen;
0
votes

Assuming this code is in a process:

screenVal <= 25;
-... snip...    
screen := update_screen(screen, 0, screenVal + 25);

screenVal won't have updated to a new value yet (unless some time passes - a wait statement between the write and the read)