std_logic向量(15 downto 0)值未分配

时间:2013-02-16 23:00:40

标签: vector variable-assignment vhdl

所以,长话短说,我试图制作各种各样的处理器(“各种各样的”因为某种原因放在那里,但是我们没有详细介绍),而且我遇到了一个问题破坏整个事物。

即,在这段代码中:

programmProcess: process (clk,rst) is
    variable counter : natural;
begin
    if (rst = '1') then
        counter := 0;
    elsif (clk'event and clk = '1' and pm_nEn= '1') then
        RAM(counter) <= data; --This is where the issue is
        counter := counter + 1;
        if (counter = 1024) then
            counter := 0;
        end if;
    end if;
    data <= "ZZZZZZZZZZZZZZZZ";
end process programmProcess;

...这是测试平台过程:

 stim_proc1: process 
 begin  
    rst <= '1';
    pm_nEn <= '1';
    wait for clk_period;

    rst <= '0' ;

    data <="0000111110111001";
    wait for clk_period;

    data <="0000111010111001";
    wait for clk_period;

    data <= "ZZZZZZZZZZZZZZZZ";
    pm_nEn <= '0';
    wait for 10*clk_period;
    wait;
end process;

...其中RAM是1024位向量的16位数组,数据是16位输入向量,pm_nEn是单位,基本上允许RAM填充值。

这个想法是RAM(计数器)从数据向量中获取值,这是在测试平台中手动输入的值,但这不会发生。即,尽管数据具有所需值,但所有RAM的值都保持“UUUUUUUUUUUUUUUUU”。即使它首次被评估并且计数器为0,RAM(0)也是未定义的。

我正在使用ISE套件,我尝试模拟,然后只是遍历所有步骤,并显示RAM(计数器)应分配值的步骤,数据向量确实具有的值是从测试平台手动添加,但RAM仍然没有获得任何值。

所以,问题基本上是 - 为什么会发生这种情况?为什么RAM没有分配它的值?

此外,这里是谷歌doc形式的完整VHDL和测试平台(由ISE方便地生成) -

VHDL

Testbench

3 个答案:

答案 0 :(得分:2)

在主进程中为“数据”分配“zzzz”应该没有坏处(尽管在当前代码片段中,它是多余的)。

可能导致合成问题的一件事是:

 elsif (clk'event and clk = '1' and pm_nEn= '1') then
    ... actions
 end if;

为了匹配合成工具对时钟进程所期望的模式,最好编写

 elsif clk'event and clk = '1' then
    if pm_nEn= '1' then
       ... actions
    end if;
 end if;

虽然我希望这两个版本在模拟中是等价的。 在另一个进程的RAM上没有其他驱动程序,是吗?

编辑:显然在另一个进程中有一个单独的驱动程序设置RAM。 现在从软件的角度来看,您可能认为这是正常的,因为一个进程在en = '0'时驱动而另一个在en = '1'时驱动。但是,在弹出布尔值时,无法使驱动程序硬件出现并消失; RAM信号上总有两个驱动程序。而你没有明确使用的那个是将值保持为“UUUU”。

最好的办法是消除其中一个。制作一个进程或另一个负责写入RAM。我会用这个过程;您可能会发现使用其他工艺设计更干净整洁;那也没关系。

这很容易:只需按以下方式重新组织这个过程:

 elsif clk'event and clk = '1' then
    if pm_nEn= '1' then
       ... actions
    else    -- or elsif external_enable then 
       RAM(external_address) <= external_data;
    end if;
 end if;

顺便提一下,当您看到RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3))))))) <= std_logic_vector(signed(OP1) + signed(OP2));这样的表达式时 它通常是一个线索,一些事情首先被声明为错误的类型:例如,OP1和OP2应该是有符号的,R应该是一个整数数组,依此类推。如果你无法消除所有的丑陋,你至少可以使用辅助函数(可能在包中)阻止它干扰主程序流:

function gen_reg_addr(IR : Register) return natural is ...

RAM(gen_reg_addr(IR)) <= ...

答案 1 :(得分:0)

我认为问题出在您写入data的众多地方。如果你有多个语句写入同一个变量,那么我不会感到惊讶,这会导致模拟器给它一个Z的值。

例如,您的某个流程如下所示:

glavenProcess: process (clk,rst) is
begin
    data <= "ZZZZZZZZZZZZZZZZ";
    ...
end process;

答案 2 :(得分:0)

很抱歉延迟,我发现你的问题,将RAM更改为变量而不是Signal,检查VHDL手册以查看信号和变量之间的差异:

        library IEEE;
use IEEE.std_logic_1164.all;
use  ieee.numeric_std.all;

entity mp is
    port(
        clk, rst, pm_nEn : in std_logic;
        data : inout std_logic_vector(15 downto 0);
       adr : out std_logic_vector(15 downto 0);
       rd_nwr : out std_logic
    );
end entity mp;

architecture beh of mp is
    signal PC, IR, OP1, OP2 : std_logic_vector(15 downto 0);
    type csignals is array(7 downto 0) of std_logic_vector(15 downto 0);
    signal R: csignals;

    type memory_array is array(1024 downto 0) of std_logic_vector(15 downto 0);
      shared variable RAM: memory_array;
begin                    

    glavenProcess: process (clk,rst) is
    begin
         data <= "ZZZZZZZZZZZZZZZZ";
        if (rst = '1') then
            PC <= "0000000000000000";
             R(0) <= "0000000000000000";
            R(1) <= "0000000000000000";
            R(2) <= "0000000000000000";
            R(3) <= "0000000000000000";
            R(4) <= "0000000000000000";
            R(5) <= "0000000000000000";
            R(6) <= "0000000000000000";
            R(7) <= "0000000000000001";
        elsif (clk'event and clk = '1' and pm_nEn= '0') then
            IR <= RAM(to_integer(unsigned(PC)));
            if (IR(15) = '0') then
                if (IR(14) = '0') then
                        OP1 <= R(to_integer(unsigned(IR(11 downto 9))));
                else
                        OP1 <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(11 downto 9)))))));
                end if;

                  if (IR(13) = '0') then
                        OP2 <= R(to_integer(unsigned(IR(8 downto 6))));
                else
                         if (IR(0) = '0') then
                                     adr <= R(to_integer(unsigned(IR(8 downto 6))));
                                     OP2 <= data;
                                     rd_nwr <= '1' ;
                         else
                                     OP2 <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(8 downto 6)))))));
                         end if;
                end if;

                if (IR(2) = '1') then OP2 <= not OP2 ; end if;
                if (IR(1) = '1') then OP1 <= not OP1 ; end if;

                  if (IR(0) = '0') then
                         if (IR(12) = '0') then
                                 R(to_integer(unsigned(IR(5 downto 3)))) <= std_logic_vector(signed(OP1) + signed(OP2));
                         else
                                 RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3))))))) := std_logic_vector(signed(OP1) + signed(OP2));
                         end if;
                   else
                         if (IR(12) = '0') then
                                 adr <= R(to_integer(unsigned(IR(5 downto 3))));
                         else
                                 adr <= RAM(to_integer(unsigned(R(to_integer(unsigned(IR(5 downto 3)))))));
                         end if;
                         data <= std_logic_vector(signed(OP1) + signed(OP2));
                         rd_nwr <= '0' ;
                   end if;
                PC <= std_logic_vector(unsigned(PC) + 1);
             else
                 if (IR(8 downto 7) = "00") then
                         if (R(to_integer(unsigned(IR(11 downto 9)))) = R(to_integer(unsigned(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "01") then
                         if (R(to_integer(signed(IR(11 downto 9)))) > R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "10") then
                         if (R(to_integer(signed(IR(11 downto 9)))) < R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 elsif (IR(8 downto 7) = "11") then
                     if ( not R(to_integer(signed(IR(11 downto 9)))) = R(to_integer(signed(IR(6 downto 4))))) then
                                 PC <= R(to_integer(unsigned(IR(14 downto 12))));
                         end if;
                 end if;
             end if;
         end if;
    end process glavenProcess;

    programmProcess: process (clk,rst) is
        variable counter : natural;
    begin
        if (rst = '1') then
            counter := 0;
        else 
            if (clk'event and clk = '1' and pm_nEn= '1')  then
            RAM(counter) := data;
            counter := counter + 1;                       
            if (counter = 1024) then counter := 0; end if;
        end if;



        end if;

    end process programmProcess;
end architecture beh;

测试平台:

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;

    -- Add your library and packages declaration here ...

entity mp_tb is
end mp_tb;

architecture TB_ARCHITECTURE of mp_tb is
    -- Component declaration of the tested unit
    component mp
    port(
        clk : in STD_LOGIC;
        rst : in STD_LOGIC;
        pm_nEn : in STD_LOGIC;
        data : inout STD_LOGIC_VECTOR(15 downto 0);
        adr : out STD_LOGIC_VECTOR(15 downto 0);
        rd_nwr : out STD_LOGIC );
    end component;

    -- Stimulus signals - signals mapped to the input and inout ports of tested entity
    signal clk : STD_LOGIC;
    signal rst : STD_LOGIC;
    signal pm_nEn : STD_LOGIC;
    signal data : STD_LOGIC_VECTOR(15 downto 0);
    -- Observed signals - signals mapped to the output ports of tested entity
    signal adr : STD_LOGIC_VECTOR(15 downto 0);
    signal rd_nwr : STD_LOGIC;

    -- Add your code here ...

begin

    -- Unit Under Test port map
    UUT : mp
        port map (
            clk => clk,
            rst => rst,
            pm_nEn => pm_nEn,
            data => data,
            adr => adr,
            rd_nwr => rd_nwr
        );   
        clock:process is
        begin           

           clk<='0';
           wait for 10 ns;
           clk<='1';
           wait for 10 ns;



        end process;
process is
begin
rst <= '1';
    pm_nEn <= '1';



    wait  for 25 ns;
    rst <= '0' ;
    data <="0000111110111001";

    wait  for 45 ns;

    data <="0000111010111001";

    wait  for 55 ns;
    data <= "ZZZZZZZZZZZZZZZZ";
    pm_nEn <= '0';

    wait;
end process;
end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_mp of mp_tb is
    for TB_ARCHITECTURE
        for UUT : mp
            use entity work.mp(beh);


        end for;
    end for;
end TESTBENCH_FOR_mp;