在vhdl中制作一个算术逻辑单元
Make an arithmetic logic unit in vhdl
我需要用 VHDL 为 pic16f684 制作一个算术逻辑单元。
因此,可以在 pic16f684 的数据表中找到 ALU 的说明。
我需要做的说明如下:
These are the instructions
到目前为止,这是我的代码,但我得到了一个 std_logic_vector 不能在向量中包含字符的错误,这很符合逻辑,但我不知道该怎么做换个方式..
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;
谢谢你们抽出时间!
WHEN "000111d" =>
或 WHEN "0101bbb" =>
等行无效,因为您的 case
语句使用 std_logic_vector
,但 "000111d"
是一个字符串。
不清楚您要用 d
和 b
字符实现什么,但是您的各种 when
行应该与有效的 std_logic_vector
正确的长度,例如 WHEN "0000111" =>
.
查看您的操作代码图像,它显示 table,其中包含包含操作的行,例如 'ADDWF'。在这些操作中,只有最高有效的 6 位似乎 select 操作,最低有效位被标记为 b
或 d
。这个最低有效位实际上是操作的参数,而不是操作码的一部分。 table 没有显示 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;
'BSF' 操作是个例外,因为它使用最低有效的 3 位作为参数。您可以使用匹配的 case 语句或通过列出一种情况下的所有可能性来编写此代码:
匹配案例,需要VHDL2008:
CASE? Op_Code (6 DOWNTO 1) IS
WHEN "0101--" =>
-- Set a bit based on `op_code (2 downto 0)`
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;
我需要用 VHDL 为 pic16f684 制作一个算术逻辑单元。 因此,可以在 pic16f684 的数据表中找到 ALU 的说明。
我需要做的说明如下:
These are the instructions
到目前为止,这是我的代码,但我得到了一个 std_logic_vector 不能在向量中包含字符的错误,这很符合逻辑,但我不知道该怎么做换个方式..
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;
谢谢你们抽出时间!
WHEN "000111d" =>
或 WHEN "0101bbb" =>
等行无效,因为您的 case
语句使用 std_logic_vector
,但 "000111d"
是一个字符串。
不清楚您要用 d
和 b
字符实现什么,但是您的各种 when
行应该与有效的 std_logic_vector
正确的长度,例如 WHEN "0000111" =>
.
查看您的操作代码图像,它显示 table,其中包含包含操作的行,例如 'ADDWF'。在这些操作中,只有最高有效的 6 位似乎 select 操作,最低有效位被标记为 b
或 d
。这个最低有效位实际上是操作的参数,而不是操作码的一部分。 table 没有显示 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;
'BSF' 操作是个例外,因为它使用最低有效的 3 位作为参数。您可以使用匹配的 case 语句或通过列出一种情况下的所有可能性来编写此代码:
匹配案例,需要VHDL2008:
CASE? Op_Code (6 DOWNTO 1) IS
WHEN "0101--" =>
-- Set a bit based on `op_code (2 downto 0)`
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;