我正在尝试将一些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关键字的条件子句
我在这些语言方面经验不足,因此,我希望能提供任何帮助
答案 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会引发上述错误。