VHDL中的信号数组?

时间:2015-05-16 19:41:13

标签: vhdl

我试图定义4096 * 16 RAM,我确实喜欢这样:

entity Test is
port(
...
IR : inout std_logic_vector(15 downto 0);
AR : inout std_logic_vector(11 downto 0));
end test

architecture test1 of test is
    type ram is array(4095 downto 0) of std_logic_vector(15 downto 0);
        signal ram1 : ram := (others => (others => '0'));
begin
AR <= "000000000000";
    ram1(0) <= "0010000000000100";
...
...
process(arguments)
    IR <= ram1(conv_integer(AR));

我的问题是,当我提供ram1值,然后将ram1值提供给输出端口时,其中的(1s)在Isim中变为未知(X)

我得到&#34; 00X000000X00&#34;对于isim中的IR

2 个答案:

答案 0 :(得分:0)

以下是RAM实体的​​同步设计:

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

entity Test is
port(
  clock : in std_logic;                      -- clock
  IR : inout std_logic_vector(15 downto 0);  -- data port
  AR : in    std_logic_vector(11 downto 0);  -- address port
  write_enable : in  std_logic               -- '1' -> write, '0' -> read

  );
end test;

architecture test1 of Test is
    type ram is array(0 to 4095) of std_logic_vector(15 downto 0);

    -- the actual ram
    signal ram1 : ram := (others => (others => '0'));

    -- internal signal for reading data
    signal IR_out : std_logic_vector(15 downto 0) := (others => 'Z');

begin

-- only apply our own signal to the data port
-- during read
IR <= IR_out when write_enable = '0' else (others => 'Z');

proc: process(clock) is
begin

  if rising_edge(clock) then
    if write_enable = '1' then

      -- write to RAM
      ram1(to_integer(unsigned(AR))) <= IR;

    else
      -- read from RAM
      IR_out <= ram1(to_integer(unsigned(AR)));      

    end if;

  end if; -- rising edge

end process;

end; -- architecture

这是一个测试平台:

library IEEE;
use IEEE.std_logic_1164.all;

entity Testbench is 
end Testbench;

architecture TB of Testbench is

   component Test
     port(
       clock : in std_logic;                      -- clock
       IR : inout std_logic_vector(15 downto 0);  -- data port
       AR : in    std_logic_vector(11 downto 0);   -- address port
       write_enable : in  std_logic              -- '1' -> write, '0' -> read
    );
   end component;

   -- define signals
   signal clock : std_logic := '0';

   -- our internal signals
   signal IRtest            : std_logic_vector(15 downto 0) := (others => 'Z');
   signal ARtest            : std_logic_vector(11 downto 0) := (others => '0');
   signal write_enable_test : std_logic := '0';

begin

   -- Instantiate a RAM to be tested and connect it to our signals
   uut: Test PORT MAP (
         clock        => clock,
         AR           => ARtest,
         IR           => IRtest,
         write_enable => write_enable_test
         );      

   -- clock generator (10 MHz)
   clockgen : process
   begin
     clock <= '0';
     wait for 50ns;
     clock <= '1';
     wait for 50ns;
   end process;

   -- generate signals to test the RAM
   stimulus : process
   begin        

     -- write data into ram
     ARtest <= "000000000000";
     IRtest <= "0010000000000100";
     write_enable_test <= '1';

     wait for 100 ns;

     -- read a different address back from RAM
     ARtest <= "000000000001";
     IRtest <= (others => 'Z');
     write_enable_test <= '0';
     wait for 100 ns;

     -- read the original address back from ram
     ARtest <= "000000000000";
     IRtest <= (others => 'Z');
     write_enable_test <= '0';
     wait for 100 ns;

     wait;


end process;


end; -- architecture

测试平台基本上在第一个时钟周期将值写入RAM,在第二个时钟周期读取不同的地址,然后在第三个时钟周期读取原始地址的内容。

测试平台的波形输出为:

waveform output of vhdl simulator

请注意,只有在时钟周期的下一个上升沿,您才能在RAM实体的​​输出端口获取RAM的内容。

你可以在这里摆弄设计和测试平台:http://www.edaplayground.com/x/5w8

我在这里也看到了异步(不使用if rising_edge(clock))示例:http://www.edaplayground.com/x/3Zs

答案 1 :(得分:0)

使用ISim时,我假设您使用Xilinx FPGA。在这种情况下,请查看Xilinx, HDL Coding Practices以推断不同类型的元素,例如的RAM。

此外,仅在设计的顶层使用inout,即使RAM位于顶层,然后将inout与RAM分开,因此综合工具可以实现不同的设计的一部分,如IO元素和RAM,正确。

基于上述论文,推断RAM的编码风格的一个例子是:

process (clk)
begin
  if (rising_edge(clk)) then
    if (we = '1') then
      mem(conv_integer(addr)) <= di ;
    else
      do <= mem(conv_integer(addr));
    end if;
  end if;
end process;