vhdl中的反转和旋转

时间:2017-01-16 14:31:37

标签: vhdl

对于学校,我们正在为ALU制作代码。代码必须使用1,2或3个输入进行计算并将其复制到输出,计算取决于4位数。

我的代码如下所示,我遇到的问题是找不到SSL SOL SRLROR运算符:

  

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;

1 个答案:

答案 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重载决策的上下文。