vhdl 等效于 verilog 中的初始块
vhdl equivalent for initial block in verilog
我正在尝试将一些 Verilog 代码转换为 VHDL。我很难将 Verilog 中的初始块正确转换为 VHDL。
据我所知,初始块对应的是没有敏感列表的流程语句,但我们必须在"end process"之前添加一个"wait"语句。我试过了但没有工作。我也尝试了其他一些方法(使用退出子句、条件子句(等待)、"for- generate" 没有进程等)但是 none 成功了。
这是我要转换的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 关键字的条件子句
我在这些语言方面没有太多经验,所以我很感激任何帮助
答案是肯定的,也不是。是的,您可以在流程的初始块中执行几乎所有操作,但在您的情况下,答案是您实际上是在初始化信号。为此你需要使用一个函数,并设置初始值:
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 的唯一原因是在 RAM 中获得 write-before-read 行为。大多数 Xilinx 推理示例都使用共享变量,这非常烦人。将您的代码切换到 VHDL2008 将引发上述错误。
具有 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 标准 1076-2000、-2002 和 -2008 的工具链中很有用,在这些工具链中,共享变量需要是受保护的类型以及早期的标准修订版。
IEEE 标准 1076-2008
9.3.3 聚合
9.3.3.1 一般:
element_association ::=
[ choices => ] expression
choices ::= choice { | choice }
您还可以使用分隔符“|”为选项提供多个值:
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 位字符串文字)。
我正在尝试将一些 Verilog 代码转换为 VHDL。我很难将 Verilog 中的初始块正确转换为 VHDL。
据我所知,初始块对应的是没有敏感列表的流程语句,但我们必须在"end process"之前添加一个"wait"语句。我试过了但没有工作。我也尝试了其他一些方法(使用退出子句、条件子句(等待)、"for- generate" 没有进程等)但是 none 成功了。
这是我要转换的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 关键字的条件子句
我在这些语言方面没有太多经验,所以我很感激任何帮助
答案是肯定的,也不是。是的,您可以在流程的初始块中执行几乎所有操作,但在您的情况下,答案是您实际上是在初始化信号。为此你需要使用一个函数,并设置初始值:
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 的唯一原因是在 RAM 中获得 write-before-read 行为。大多数 Xilinx 推理示例都使用共享变量,这非常烦人。将您的代码切换到 VHDL2008 将引发上述错误。
具有 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 标准 1076-2000、-2002 和 -2008 的工具链中很有用,在这些工具链中,共享变量需要是受保护的类型以及早期的标准修订版。
IEEE 标准 1076-2008
9.3.3 聚合
9.3.3.1 一般:
element_association ::=
[ choices => ] expression
choices ::= choice { | choice }
您还可以使用分隔符“|”为选项提供多个值:
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 位字符串文字)。