对于学校,我们正在为ALU制作代码。代码必须使用1,2或3个输入进行计算并将其复制到输出,计算取决于4位数。
我的代码如下所示,我遇到的问题是找不到SSL
SOL
SRL
和ROR
运算符:
final_ex.vhd(34):无法确定运营商的定义"" sll"" - 找到0个可能的定义
final_ex.vhd(35):无法确定运营商的定义"" rol"" - 找到0个可能的定义
final_ex.vhd(36):无法确定运营商的定义"" srl"" - 找到0个可能的定义
final_ex.vhd(37):无法确定运营商的定义"" ror"" - 找到0个可能的定义
我的vdhl是在2008年,因此无法与版本相关。我尝试使用std_logic_vector
代替unsigned
,我尝试使用普通的4位数字,例如" 0101"但每次都有同样的错误。
我尝试了不同的数据类型,但它不会工作。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY final_ex IS
GENERIC(N: INTEGER:= 4); -- length of the inputs and output
PORT(
A, B: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
functions: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clock, Setflag, Zeroflag: IN STD_LOGIC;
C: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0)
);
END ENTITY;
ARCHITECTURE alu OF final_ex IS
SIGNAL a_sig, b_sig: SIGNED(N-1 DOWNTO 0);
SIGNAL c_sig: SIGNED(N-1 DOWNTO 0);
SIGNAL c_unsig: STD_LOGIC_VECTOR(N-1 DOWNTO 0);
SIGNAL carry: INTEGER RANGE 0 TO 1;
SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0);
BEGIN
a_unsig <= UNSIGNED(A);
---------Logic Unit----------- ( with unsigned output for logic, bitwise operators )
WITH functions(2 DOWNTO 0) SELECT
c_unsig <= A AND B WHEN "000",
A OR B WHEN "001",
A XOR B WHEN "010",
NOT A WHEN "011",
a_unsig SLL 1 WHEN "100",
a_unsig ROL 1 WHEN "101",
a_unsig SRL 1 WHEN "110",
a_unsig ROR 1 WHEN OTHERS;
---------- Arithmetic Unic:---------- ( signed for calcualtions with integers )
a_sig <= SIGNED(A);
b_sig <= SIGNED(B);
carry <= 1 WHEN Setflag = '1' Else 0;
WITH functions(2 DOWNTO 0) SELECT
c_sig <= "0000" WHEN "000",
a_sig WHEN "001",
a_sig + 1 WHEN "010",
a_sig - 1 WHEN "011",
a_sig + b_sig WHEN "100",
a_sig + b_sig + carry WHEN "101",
a_sig - b_sig WHEN "110",
a_sig - b_sig - carry WHEN OTHERS;
-----------------------------------------------------------------------------
WITH functions(3) SELECT
c <= c_unsig WHEN '1',
STD_LOGIC_VECTOR(c_sig) WHEN OTHERS;
END ARCHITECTURE;
答案 0 :(得分:2)
如果你密切关注c_unsig
的类型是std_logic_vector
。没有预定义的运算符&#34; sll&#34;,&#34; rol&#34;,&#34; srl&#34;和&#34; ror&#34;带有签名[unsigned,integer return std_logic_vector](在-2008 numeric_std包中,unsigned将是基本类型UNRESOLVED_UNSIGNED)。
有三种方法可以解决这个问题。
使用类型转换:
WITH functions(2 DOWNTO 0) SELECT
c_unsig <= A AND B WHEN "000",
A OR B WHEN "001",
A XOR B WHEN "010",
NOT A WHEN "011",
std_logic_vector(a_unsig SLL 1) WHEN "100",
std_logic_vector(a_unsig ROL 1) WHEN "101",
std_logic_vector(a_unsig SRL 1) WHEN "110",
std_logic_vector(a_unsig ROR 1) WHEN OTHERS;
这依赖于包numeric_std中声明的函数的签名。
更改c_unsig的类型:
SIGNAL c_unsig: unsigned(N-1 DOWNTO 0);
SIGNAL carry: INTEGER RANGE 0 TO 1;
SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0);
BEGIN
a_unsig <= UNSIGNED(A);
---------Logic Unit----------- ( with unsigned output for logic, bitwise operators )
WITH functions(2 DOWNTO 0) SELECT
c_unsig <= unsigned (A AND B ) WHEN "000",
unsigned (A OR B) WHEN "001",
unsigned (A XOR B) WHEN "010",
unsigned ( NOT A ) WHEN "011",
a_unsig SLL 1 WHEN "100",
a_unsig ROL 1 WHEN "101",
a_unsig SRL 1 WHEN "110",
a_unsig ROR 1 WHEN OTHERS;
---------- Arithmetic Unic:---------- ( signed for calcualtions with integers )
a_sig <= SIGNED(A);
b_sig <= SIGNED(B);
carry <= 1 WHEN Setflag = '1' Else 0;
WITH functions(2 DOWNTO 0) SELECT
c_sig <= "0000" WHEN "000",
a_sig WHEN "001",
a_sig + 1 WHEN "010",
a_sig - 1 WHEN "011",
a_sig + b_sig WHEN "100",
a_sig + b_sig + carry WHEN "101",
a_sig - b_sig WHEN "110",
a_sig - b_sig - carry WHEN OTHERS;
-----------------------------------------------------------------------------
WITH functions(3) SELECT
c <= std_logic_vector(c_unsig) WHEN '1',
STD_LOGIC_VECTOR(c_sig) WHEN OTHERS;
END ARCHITECTURE;
这需要再进行一次类型转换。
更改c_unsig的类型并添加b_unsig:
SIGNAL c_unsig: unsigned(n-1 downto 0); -- STD_LOGIC_VECTOR(N-1 DOWNTO 0);
SIGNAL carry: INTEGER RANGE 0 TO 1;
SIGNAL a_unsig: UNSIGNED(N-1 DOWNTO 0);
signal b_unsig: unsigned(n-1 downto 0);
BEGIN
a_unsig <= UNSIGNED(A);
b_unsig <= unsigned(B);
---------Logic Unit----------- ( with unsigned output for logic, bitwise operators )
WITH functions(2 DOWNTO 0) SELECT
c_unsig <= a_unsig AND b_unsig WHEN "000",
a_unsig OR b_unsig WHEN "001",
a_unsig XOR b_unsig WHEN "010",
NOT a_unsig WHEN "011",
a_unsig SLL 1 WHEN "100",
a_unsig ROL 1 WHEN "101",
a_unsig SRL 1 WHEN "110",
a_unsig ROR 1 WHEN OTHERS;
---------- Arithmetic Unic:---------- ( signed for calcualtions with integers )
a_sig <= SIGNED(A);
b_sig <= SIGNED(B);
carry <= 1 WHEN Setflag = '1' Else 0;
WITH functions(2 DOWNTO 0) SELECT
c_sig <= "0000" WHEN "000",
a_sig WHEN "001",
a_sig + 1 WHEN "010",
a_sig - 1 WHEN "011",
a_sig + b_sig WHEN "100",
a_sig + b_sig + carry WHEN "101",
a_sig - b_sig WHEN "110",
a_sig - b_sig - carry WHEN OTHERS;
-----------------------------------------------------------------------------
WITH functions(3) SELECT
c <= std_logic_vector(c_unsig) WHEN '1',
STD_LOGIC_VECTOR(c_sig) WHEN OTHERS;
这符合您对签名操作的使用。
所有三个变化都要进行分析和阐述。如果没有测试平台生成clock
和其他各种输入,则边界检查尚未经过验证。
此代码不依赖于-2008。
VHDL是一种强类型语言,根据指定输入类型和返回类型的签名,实现运算符的函数符合运算符重载的条件。
参见IEEE Std 1076-2008 4.5.2运算符重载,4.5.3签名,9.2运算符,9.3.6类型转换和12.5重载决策的上下文。