所以,长话短说,我试图制作各种各样的处理器(“各种各样的”因为某种原因放在那里,但是我们没有详细介绍),而且我遇到了一个问题破坏整个事物。
即,在这段代码中:
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方便地生成) -
答案 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;