问题
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?
回答1:
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;
回答2:
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)
来源:https://stackoverflow.com/questions/6811386/vhdl-integerimage-returns-0