VHDL integer'image返回“0”

时间:2011-07-25 02:53:52

标签: image attributes vhdl

这是我的困境:

我是VHDL编程的新手,我目前正在为大学课程开展一个独立的学习项目。我已经取得了一些进展,但我遇到了一个我无法解决的问题。

我要做的是在LCD显示器上显示“寄存器”(或寄存器)并定期更新。目前,这些值将始终为整数。

我编写的代码在屏幕上正确显示数字如果该值作为一个永远不会改变的变量作为硬编码值传递。但是,我想通过添加变量来更新变量,然后将其传递给我的函数并显示它。

基本上我要做的是:

每个'x'时钟滴答,递增寄存器的值,将其传递给我的update_screen函数,该函数返回一个新屏幕,然后在下面显示。但是,一旦我通过重新分配增加或改变(如果它是变量或信号似乎没有关系),我在屏幕上看到的只是'0'。

所以...以下代码正确更新我的显示,除非我取消注释注释行。那时,它只显示'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);

问题似乎源于整数'图像属性(或更准确地说,我对它的理解)。当我传入硬编码值或未改变的变量时,它会返回我期望的值。但是,只要我以任何方式修改变量/信号,它似乎返回字符串“0”。

以下是我的update_screen功能:

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;

一些重点(2011-07-26补充):

  • 我正在使用Quartus II免费(网络版)来设计/编译我的项目。
  • 正在更新变量的代码正在进行中。
  • 在原始发布时,我采取的唯一步骤是编译我的代码并编写Altera DE2 FPGA板并得到结果(我不知道如何执行任何类型的模拟)。

提前感谢您的任何帮助和建议。另外,正如我所说的,我是VHDL编程的新手,所以如果有更好的方法来做我在这里做的事情,请告诉我。我也非常感谢有关语言本身的任何资源的有用链接。

更新(2011-07-26):

我按照Martin Thompson的建议下载了GHDL,但我还没有实际使用它,因为我不知道如何使用我目前的Quartus II项目(或者如果我可以的话)这样做。在对我有用之前,我必须做一些阅读。然而,昨天我设法安装了ModelSim-Altera,它直接与Quartus II一起工作,并允许我进行一些模拟。

我尽力设置一些允许我测试的波形,我至少能够检查我认为失败的代码的执行情况。但是,在模拟过程中,我已经通过多种方式验证了“screen”对象确实包含了我希望它在* screen_update *函数运行后包含的值。但是,当在Altera DE2上运行时,它仍然会失败。

  • 注意:我确实通过直接将屏幕上特定元素的值设置为不同的值来验证屏幕实际更新,具体取决于 currentRegVal 是偶数还是奇数。

我计划明天发布一些代码,但现在:

模拟会提供不同结果的原因是什么?我的猜测是适时的,但实际上只是猜测。如果我是对的,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我猜这个问题与您将strRegVal声明为constant的事实有关。我认为最好是variable,例如这样的事情可能有用:

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;

答案 1 :(得分:0)

假设此代码正在进行中:

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

screenVal还没有更新到新值(除非一些时间过去了 - 写入和读取之间的wait语句)