vhdl等效于verilog中的初始块

时间:2019-07-02 12:52:42

标签: vhdl verilog

我正在尝试将一些Verilog代码转换为VHDL。我很难将Verilog中的初始块正确转换为VHDL。

据我所知,初始块对应于没有敏感度列表的process语句,但是我们必须在“ end process”之前添加“ wait”语句。我尝试了一下,但是没有用。我也尝试了其他一些方法(使用exit子句,条件子句(等到),没有进程的“ for-generate”等),但没有一个成功。

这是我要转换的Verilog代码,它可以正常工作

module MyRAM  #(parameter DATA_WIDTH=24, parameter ADDR_WIDTH=10)
(
input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] read_addr, write_addr,
input we, clk,
output reg [(DATA_WIDTH-1):0] q
);

// Declare the RAM variable
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];

initial 
begin : INIT
    integer i;


    for(i = 1; i < ((2**ADDR_WIDTH)-1); i = i+1) begin
        if (i == 132)   ram[i]   = 24'h550000;
        else if (i == 133)  ram[i]   = 24'h005500;
        else if (i == 134)  ram[i]   = 24'h000055;
        else    ram[i]   = 24'h000000;
    end
    //*/
end 

always @ (negedge clk)
begin
    // Write
    if (we)
        ram[write_addr] <= data;
        q <= ram[read_addr];
end

endmodule

这是我到目前为止编写的VHDL代码:

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


entity MyRAM is 
generic
(DATA_WIDTH: integer;
ADDR_WIDTH: integer);

port
(
data :in std_logic_vector ((DATA_WIDTH-1) downto 0);
read_addr :in std_logic_vector((ADDR_WIDTH-1) downto 0);
write_addr :in std_logic_vector(( DATA_WIDTH-1) downto 0);
we :in std_logic;
clk :in std_logic;
q :out std_logic_vector( 23 downto 0)
);
end MyRAM;

    architecture behavioral of MyRAM is

  constant case1:std_logic_vector(23 downto 0):= 
 (16=>'1',18=>'1',20=>'1',22=>'1',others=>'0');
 constant case2:std_logic_vector(23 downto 0):= 
 (8=>'1',10=>'1',12=>'1',14=>'1',others=>'0');
 constant case3:std_logic_vector(23 downto 0):= 
 (0=>'1',2=>'1',4=>'1',6=>'1',others=>'0');

   type ram is array ( 0 to (2**ADDR_WIDTH-1)) of 
   std_logic_vector((DATA_WIDTH-1) downto 0); 


    shared variable origram:ram;
    signal s_q: std_logic_vector(23 downto 0);

   begin

    process
    begin 

    for ii in 1 to (2**ADDR_WIDTH-1)  loop  
    if (ii = 132) then
                 origram(ii)  := case1;

        elsif (ii = 133) then
                 origram(ii)  := case2;

        elsif (ii = 134) then   
             origram(ii)  := case3;
    else  
                origram(ii)  :=(others=>'0');           
        end if;
  end loop;
  wait;

 end process;   


 process (clk)

 begin   
    if falling_edge(clk) then


      if (we ='1') then 
         origram(to_integer(unsigned(write_addr))) := data;
         s_q <= origram(to_integer(unsigned(read_addr)));
      end if;
      end if;
  end process;     

  q<=s_q;
end behavioral;  

这是错误消息: 错误(10533):MyRAM.vhd(88)上的VHDL等待语句错误:等待语句必须包含带有UNTIL关键字的条件子句

我在这些语言方面经验不足,因此,我希望能提供任何帮助

2 个答案:

答案 0 :(得分:1)

使用ram变量而不是共享变量的过程也可以提供初始值:

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

entity MyRAM is 
    generic (
        DATA_WIDTH: integer;
        ADDR_WIDTH: integer
    );
    port (
        data:       in  std_logic_vector (DATA_WIDTH - 1 downto 0);
        read_addr:  in  std_logic_vector (ADDR_WIDTH - 1 downto 0);
        write_addr: in  std_logic_vector (DATA_WIDTH - 1 downto 0);
        we:         in  std_logic;
        clk:        in  std_logic;
        q:          out std_logic_vector (DATA_WIDTH - 1 downto 0)
    );
end entity MyRAM;

architecture behavioral of MyRAM is
    constant case1: std_logic_vector(23 downto 0) := 
        (16 => '1', 18 => '1', 20 => '1', 22 => '1', others => '0');
    constant case2: std_logic_vector(23 downto 0) := 
        ( 8 => '1', 10 => '1', 12 => '1', 14 => '1', others => '0');
    constant case3: std_logic_vector(23 downto 0) := 
        ( 0 => '1',  2 => '1',  4 => '1',  6 => '1', others => '0');
    type ram is array ( 0 to 2 ** ADDR_WIDTH - 1) of 
        std_logic_vector(DATA_WIDTH - 1 downto 0); 
begin

MY_RAM:
    process (clk)
        function init_origram return ram is
            variable ramval:    ram;
        begin
                for ii in ram'left to ram'right  loop
                if ii = 132 then  -- note the presumption ram has at least 135 elements
                    ramval(ii)  := case1;
                elsif ii = 133 then
                    ramval(ii)  := case2;
                elsif ii = 134 then
                    ramval(ii)  := case3;
                else
                    ramval(ii)  := (others => '0');
                end if;
            end loop;
            return ramval;
        end function;
        variable origram: ram := init_origram;
    begin
        if falling_edge(clk) then
            if we = '1' then  -- write before read
                origram(to_integer(unsigned(write_addr))) := data;
            end if;
            q <= origram(to_integer(unsigned(read_addr)));
        end if;
    end process;
end architecture behavioral;

这在IEEE Std 1076-2000,-2002和-2008兼容工具链中很有用,在这些工具链中,共享变量必须是受保护的类型以及较早的标准修订版。

IEEE Std 1076-2008
9.3.3骨料 9.3.3.1常规:

  

element_association :: =
  [选择=>]表达式
  选择:: =选择{|选择}

您还可以使用分隔符'|`为选择提供多个值:

    constant case1: std_logic_vector(23 downto 0) := 
        -- (16 => '1', 18 => '1', 20 => '1', 22 => '1', others => '0');
        (16 | 18 | 20 | 22 => '1', others => '0');

甚至在此处提供十六进制值的基本说明符X位字符串(15.8位字符串文字)。

答案 1 :(得分:0)

答案是是和不是。是的,您可以在流程的初始块中执行几乎所有的操作,但是根据您的情况,答案是您实际上是在初始化信号。为此,您需要使用一个函数,并设置初始值:

type ram is array ( 0 to (2**ADDR_WIDTH-1)) of std_logic_vector((DATA_WIDTH-1) downto 0); 

function init_ram return ram is
  variable r : ram;
begin
  -- set the contents of the ram
end function init_ram;

shared variable origram:ram := init_ram;

最后等待的过程仅用于仿真(这将模仿Verilog中用于测试平台刺激的初始块)

注意:从VHDL 2002开始,使用这样的共享变量是非法的,因为它应该是受保护的类型(当前无法合成)。您可能希望共享变量(而不是信号)来推断内存的唯一原因是要在RAM中获得先写后读行为。大多数Xilinx Inference示例都使用共享变量,这非常令人讨厌。将您的代码切换到VHDL2008会引发上述错误。