读取,然后写入RAM VHDL

时间:2016-08-22 14:40:26

标签: vhdl fpga ram cpu-architecture xilinx

在VHDL中,所有代码行都以并行方式执行,因为它是一台机器。 我想创建这个RAM,从一个ram块读取一个特定的寄存器到输出,然后只有'写入相同的寄存器输入。我的代码是这样的:

architecture Behavioral of RAM is

type ram_t is array (0 to numOfRegs-1) of std_logic_vector (rLength-1 downto 0);
signal ram_s: ram_t;
signal loc : integer;

begin

process(clk)
begin
    if(rising_edge(clk)) then
        if(we='1') then
            dataout <= ram_s(loc); -- reads the 'old' data to the output 
            ram_s(loc) <= datain;  --  writes the 'new' data to the RAM
            loc <= conv_integer(addr);
        end if;
    end if;
end process;                
end Behavioral;

有一个类似的案例 here

所以我想问一下,我的代码工作正常还是需要进行调整,比如延迟半个时钟周期,如果有的话,如何实现它。 感谢您的耐心和帮助,我对VHDL非常陌生。

我在下面添加了一个测试平台模拟。可以看出数据输出根本不起作用。

testbench i've simulated

1 个答案:

答案 0 :(得分:1)

您的问题不会显示Minimal, Verifiable and Complete example,但无法复制您的搜索结果。

其中一个后果是,如果代码中未显示的部分问题有一个或多个原因导致答案可能不明确。

Brian评论说,当我们无效时,您不能读取数据是很尖锐的,并且会在波形中黄色标记左侧的时钟周期内负责#U

还有class Environment { public string Name { get; private set; } public string Description { get; private set; } public bool ContainsItems { get; set; } public bool ContainsEntities { get; set; } public static List<Environment> Environments = new List<Environment>(); public Environment(string name, string description, bool containsItems, bool containEntities) { Name = name; Description = description; ContainsItems = containsItems; ContainsEntities = containEntities; } public void SetLocation() { Console.Clear(); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(); DisplayText("You arrived at {0}", Name); DisplayText(Description); Console.ReadKey(); if (ContainsItems) { Console.ForegroundColor = ConsoleColor.Yellow; DisplayText("If you look carefully, you might find something valuable!"); if(ContainsEntities) { Console.ForegroundColor = ConsoleColor.Red; DisplayText("Proceed with caution, some monsters hides here!"); } } Console.ForegroundColor = ConsoleColor.White; } } 作为信号的问题。信号被安排更新,并且在计划在当前模拟周期中恢复的任何进程尚未恢复和暂停时,不会进行更新。

这意味着您的地址的整数版本会延迟,并且在此过程中不会被看到,直到下一个上升沿。

通过将loc变为流水线loc的替代方法并移动datain分配来修复dataout,可以通过以下对RAM流程的更改来完成:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;  -- standard package

entity ram is
    generic (
        ADDRLENGTH: natural := 8;
        RLENGTH:    natural := 16;
        NUMOFREGS:  natural := 256
    );
    port (
        clk:        in  std_logic;
        we:         in  std_logic;
        addr:       in  std_logic_vector (ADDRLENGTH - 1 downto 0);
        datain:     in  std_logic_vector (RLENGTH - 1 downto 0);
        dataout:    out std_logic_vector (RLENGTH - 1 downto 0)
    );

end entity;

architecture behavioral of ram is

    type ram_t is array (0 to NUMOFREGS - 1) of 
            std_logic_vector (RLENGTH - 1 downto 0);
    signal ram_s: ram_t;

    -- signal loc: integer;  -- USE VARIABLE in process instead

begin

    process(clk)
    variable loc: integer;   -- MAKE loc variable so it's immediately available
    begin
        if rising_edge(clk) then
            loc := to_integer(unsigned(addr)); -- MOVED so READ works
            if we = '1' then
                -- dataout <= ram_s(loc); -- reads the 'old' data to the output 
                ram_s(loc) <= datain;  --  writes the 'new' data to the ram
                -- loc <= conv_integer(addr);
            end if;
            dataout <= ram_s(loc); -- MOVED reads the 'old' data to the output 
        end if;
    end process;                
end architecture behavioral;

还可以自由填写实体声明并使用Synopsys的软件包std_logic_arith从conv_integer转换为IEEE的numeric_std软件包中的to_integer。使用符合-2008标准的工具链,您可以使用IEEE的数据包numeric_std_unsigned,并将类型转换为无符号。

由于还没有提供ram_test测试平台,因此编写了一个测试平台来复制波形显示图像:

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

entity ram_tb is
end entity;

architecture foo of ram_tb is
    constant ADDRLENGTH: natural := 8;
    constant RLENGTH:    natural := 16;
    constant NUMOFREGS:  natural := 256;
    signal clk:        std_logic := '0';
    signal we:         std_logic := '1';
    signal addr:       std_logic_vector (ADDRLENGTH - 1 downto 0);
    signal datain:     std_logic_vector (RLENGTH - 1 downto 0);
    signal dataout:    std_logic_vector (RLENGTH - 1 downto 0);

begin
DUT:
    entity work.ram
        generic map (
            ADDRLENGTH => ADDRLENGTH,
            RLENGTH => RLENGTH,
            NUMOFREGS => NUMOFREGS
        )
        port map (
            clk => clk,
            we => we,
            addr => addr,
            datain => datain,
            dataout => dataout
        );

CLOCK:
    process
    begin
        if now = 500 ps then
            wait for 200 ps;
        else 
            wait for 100 ps;
        end if;
        clk <= not clk;
        if now >= 1100 ps then
            wait;
        end if;
    end process;

STIMULI:
    process
    begin
        for i in 0 to 2 loop
            addr   <= std_logic_vector(to_unsigned (i, ADDRLENGTH));
            case i is
                when 0 =>
                    datain <= x"00FF";
                when 1 =>
                    datain <= x"FF00";
                when 2 =>
                    datain <= x"FFFF";
            end case;
            wait until falling_edge(clk);
            if i = 1 then
                we <= '0';
            end if;
        end loop;
        for i in 1 to 2 loop
            addr   <= std_logic_vector(to_unsigned (i, ADDRLENGTH));
            case i is
                when 1 =>
                    datain <= x"FF00";
                when 2 =>
                    datain <= x"FFFF";
            end case;
            wait until falling_edge(clk);
        end loop;        
        wait;
    end process;

end architecture;

这产生了:

ram_tb_match.png

随后读取的一个写入地址显示正确的数据。

使用的模拟器不会在波形转储中显示非信号(声明中的边界必须是静态的),并且在提供的设计规范部分中找不到rst

如前所述,我们无法保证您的设计规范或测试平台的部分内容未在您的问题中提供。

显示的测试平台并不全面。