1

所以,长话短说,我正在尝试制作一个处理器('of sorts' 放在那里是有原因的,但我们不去详细说明),我遇到了一个几乎毁了整个处理器的问题事物。

即,在这段代码中:

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(counter) 从数据向量中获取值,这是在测试台中手动输入的值,但这不会发生。也就是说,尽管数据具有所需的值,但所有 RAM 的值都只是保持“UUUUUUUUUUUUUUUU”。即使第一次评估并且计数器为 0,RAM(0) 也是未定义的。

我正在使用 ISE 套件,我尝试模拟,然后只是跟踪所有步骤,并显示 RAM(counter) 应该被分配一个值的步骤,数据向量确实具有手动添加的值测试台,但 RAM 仍然没有得到任何值。

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

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

高密度脂蛋白

试验台

4

3 回答 3

2

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

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

 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。现在从软件的角度来看,您可能认为这没问题,因为一个进程驱动 whenen = '0'和另一个 when 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)) <= ...
于 2013-02-16T23:41:38.877 回答
0

我想问题出在你写信的地方很多data。如果您有多个语句写入同一个变量,我不会感到惊讶,这应该会导致模拟器给它一个Z.

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

glavenProcess: process (clk,rst) is
begin
    data <= "ZZZZZZZZZZZZZZZZ";
    ...
end process;
于 2013-02-16T23:05:43.753 回答
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;
于 2013-02-16T23:23:11.793 回答