用vhdl语言制作算术逻辑单元

用vhdl语言制作算术逻辑单元,vhdl,quartus,alu,Vhdl,Quartus,Alu,我需要用VHDL为pic16f684制作一个算术逻辑单元。 因此,可以在pic16f684的数据表中找到ALU的说明 我需要做的说明如下: 这是到目前为止我的代码,但我得到了一个非常符合逻辑的错误,一个std_logic_向量不能在向量中包含字符,但我不知道如何用另一种方式来实现 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all;

我需要用VHDL为pic16f684制作一个算术逻辑单元。 因此,可以在pic16f684的数据表中找到ALU的说明

我需要做的说明如下:

这是到目前为止我的代码,但我得到了一个非常符合逻辑的错误,一个std_logic_向量不能在向量中包含字符,但我不知道如何用另一种方式来实现

LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY AluPIC IS

   PORT(    -- Input Signals    
        Op_code     : in std_logic_vector(6 DOWNTO 0);
        win, fin        : in std_logic_vector(7 DOWNTO 0);
         -- Output Signals
        d,z : out std_logic;
        ALU_output  : out std_logic_vector(7 DOWNTO 0));


END AluPIC;

ARCHITECTURE behavior OF AluPIC IS
        -- declare signal(s) internal to module here
SIGNAL temp_output,wout,fout: std_logic_vector(7 DOWNTO 0);

BEGIN
  PROCESS (Op_code, win, fin)
    BEGIN
        -- Select Arithmetic/Logical Operation
    CASE Op_Code (6 DOWNTO 0) IS
        WHEN "000111d" =>
            if d ='0' then
                wout <= win + fin;
                temp_output <=wout;
            else
                fout <= win + fin;
                temp_output <= fout;
            end if;

        WHEN "000101d" =>
            if d ='0' then
                wout <= win and fin;
                temp_output <= wout;
            else
                fout <= win and fin;
                temp_output <= fout;
            end if;

        WHEN "000001l" =>
             fout <= fin;
             fout <= "00000000";
             z <= '1';
             temp_output <= fout;

        WHEN "001010d" =>
            fout <= fin+1;
             if d = '0' then
                wout <= fout;
                temp_output <=wout;
             else
                fout <= fout;
                temp_output <=fout;
            end if;

        WHEN "001000d" =>
        if d = '0' then
            wout  <= fin;
            temp_output <= wout;
            z <= '1';
        else
            fout <= fin;
            temp_output <= fout;
            z <= '1';
        end if;

        WHEN "0101bbb" =>
            fout <= fin;
             temp_output <= fout;
        WHEN OTHERS =>
            temp_output <= "00000000";
    END CASE;
            -- Select Shift Operation
    IF Op_Code(0) = '1' THEN
            -- Shift bits left with zero fill using concatination operator
            -- can also use VHDL 1076-1993 shift operator such as SLL 
        Alu_output <= temp_output(6 DOWNTO 0) & '0';
    ELSE 
        Alu_output <= temp_output;
    END IF;
  END PROCESS;
END behavior;
IEEE库;
使用IEEE.STD_LOGIC_1164.all;
使用IEEE.STD_LOGIC_ARITH.all;
使用IEEE.STD_LOGIC_UNSIGNED.all;
实体AluPIC是
端口(-)输入信号
操作码:标准逻辑向量(6到0);
win,fin:标准逻辑向量(7到0);
--输出信号
d、 z:输出标准逻辑;
ALU_输出:输出标准逻辑向量(7到0);
末端AluPIC;
AluPIC的架构行为是
--在此声明模块内部的信号
信号温度输出,wout,fout:标准逻辑向量(7到0);
开始
流程(Op_代码、win、fin)
开始
--选择算术/逻辑运算
案例Op_代码(6至0)为
当“000111d”=>
如果d='0',则
因为您的
case
语句使用了
标准逻辑向量
,但
000111d
是一个字符串,所以当“000111d”=>
或“0101bbb”=>时像
这样的行无效

使用
d
b
字符试图实现什么还不清楚,但您的各种
when
行应与正确长度的有效
std\u逻辑向量
进行比较,例如
when“0000111”=>

查看操作代码图像,它显示了一个表,其中包含包含操作的行,例如“ADDWF”。在这些操作中,似乎只有最高有效的6位选择操作,最低有效位被标记为
b
d
。这个最低有效位实际上是操作的参数,而不是操作码的一部分。该表没有显示
d
对操作的影响,但您似乎已经解决了这个问题。以
ADDWF
为例,我将如下更改您的代码:

CASE Op_Code (6 DOWNTO 1) IS
  WHEN "000111" =>
    if Op_Code(0) ='0' then
      wout <= win + fin;
      temp_output <=wout;
    else
      fout <= win + fin;
      temp_output <= fout;
    end if;
  -- ...
end case;
列出所有可能性:

CASE Op_Code (6 DOWNTO 1) IS
  WHEN "010100" | "010101" | "010110" | "010111" =>
    -- Set a bit based on `op_code (2 downto 0)`
end case;

到目前为止,这是清楚的,但我怎样才能用另一种方式解决这个问题呢?因为如果你看一下说明书,就会发现使用了01bb,我怎样才能把这个说明书放到std_逻辑_向量中呢?你必须更深入地阅读PIC手册,才能理解
bb
d
的意思,并做出相应的修改。好的@Faalhaaz我想我理解了这个问题,请看我的编辑。非常感谢!,它不仅给了我解决方案,而且现在我对它的理解好多了!顺便说一句,杰夫,你是谁?在案例陈述之后,这意味着什么?
CASE Op_Code (6 DOWNTO 1) IS
  WHEN "010100" | "010101" | "010110" | "010111" =>
    -- Set a bit based on `op_code (2 downto 0)`
end case;