英文:
Cannot convert type STD_Logic to type unsigned
问题
以下是代码的翻译部分:
&我正试图在32位MIPS单周期处理器的ALU中创建无符号加法的逻辑,但一直出现以下错误:
无法将类型逻辑转换为类型无符号
到目前为止,这是我的代码(请随意查看,我觉得大部分都在那里,但某些逻辑可能有点问题):
库IEEE;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.STD_LOGIC_UNSIGNED.ALL;
使用ieee.numeric_std.all;
使用IEEE.STD_LOGIC_UNSIGNED.ALL;
实体ALU是
端口(
A:in STD_LOGIC_VECTOR(31 downto 0);
B:in STD_LOGIC_VECTOR(31 downto 0);
A_u,B_u:in unsigned(31 downto 0);
ALUCntl:in STD_LOGIC_VECTOR(3 downto 0);
Carryin:in STD_LOGIC;
ALUOut:out STD_LOGIC_VECTOR(31 downto 0);
Zero:out STD_LOGIC;
Carryout:out std_logic;
Overflow:out STD_LOGIC
);
end ALU;
体系结构ALU的行为是
信号ALU_Result:std_logic_vector(31 downto 0);
信号add_result,sub_result,a32,b32,c32:std_logic_vector(32 downto 0):=(其他 => '0');
信号add_ov,sub_ov:std_logic;
开始
-- 加法,减法和位操作
使用ALUCntl选择
ALU_Result <= add_result(31 downto 0) when "0010", -- 加法
sub_result(31 downto 0) when "0110", -- 减法
A AND B when "0000",
A OR B when "0001",
A XOR B when "0011",
A NOR B when "1100",
A when others; ---所有其他ALU控制信号的条件
ALUOut <= ALU_Result;
-- 加法操作和进位生成
a32 <= '0' & A;
b32 <= '0' & B;
c32(0) <= Carryin;
add_result <= a32 + b32 + c32;
sub_result <= a32 - b32;
-- 无符号加法
使用ALUCntl选择
add_result <= std_logic_vector(unsigned(A_u) + unsigned(B_u) + unsigned(Carryin)) when "0010",
std_logic_vector(unsigned(A_u) + unsigned(B_u)) when "0101",
(其他 => '0') when others;
ALU_Result <= add_result(31 downto 0);
-- 无符号减法
sub_result <= std_logic_vector(unsigned(A_u) - unsigned(B_u));
ALU_Result <= sub_result(31 downto 0) when ALUCntl = "0100" else ALU_Result;
-- 零标志
Zero <= '1' when ALU_Result = x"00000000" else '0';
-- 溢出标志
add_ov <= (A(31) and B(31) and (not ALU_Result(31))) or ((not A(31)) and (not B(31)) and ALU_Result(31));
sub_ov <= (A(31) and (not B(31)) and (not ALU_Result(31))) or ((not A(31)) and B(31) and ALU_Result(31));
使用ALUCntl选择
溢出 <= add_ov when "0010",
sub_ov when "0110",
'Z' when others;
-- 进位输出
使用ALUCntl选择
Carryout <= add_result(32) when "0010",
sub_result(32) when "0110",
'Z' when others;
过程(ALUCntl,A,B)
开始
-- 有符号SLT
如果(ALUCntl = "1001")然后
如果(signed(A) < signed(B))然后
ALU_Result <= "00000001"; -- 如果A < B,则将ALU输出设置为1
其他
ALU_Result <= "00000000"; -- 如果A >= B,则将ALU输出设置为0
结束 if;
结束 if;
-- 无符号SLT
如果(ALUCntl = "1010")然后
如果(unsigned(A) < unsigned(B))然后
ALU_Result <= "00000001"; -- 如果A < B,则将ALU输出设置为1
其他
ALU_Result <= "00000000"; -- 如果A >= B,则将ALU输出设置为0
结束 if;
结束 if;
end process;
end Behavioral;
请注意,我已经将代码中的注释和代码部分翻译为中文。如果您有任何其他问题,请随时提出。
英文:
&I am trying to create the logic for unsigned addition in the ALU of a 32-bit MIPS single cycle processor but keep getting this error:
cannot convert type logic to type unsigned
This is what I have so far (Feel free to look through it,I feel like its mostly there but I might be a bit off with some of the logic :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU is
Port (
A: in STD_LOGIC_VECTOR (31 downto 0);
B: in STD_LOGIC_VECTOR (31 downto 0);
A_u,B_u:in unsigned(31 downto 0);
ALUCntl: in STD_LOGIC_VECTOR (3 downto 0);
Carryin: in STD_LOGIC;
ALUOut: out STD_LOGIC_VECTOR (31 downto 0);
Zero: out STD_LOGIC;
Carryout: out std_logic;
Overflow: out STD_LOGIC
);
end ALU;
architecture Behavioral of ALU is
signal ALU_Result : std_logic_vector (31 downto 0);
signal add_result, sub_result, a32, b32, c32: std_logic_vector(32 downto 0) := (others => '0');
signal add_ov, sub_ov: std_logic;
begin
-- Add, Sub, and Bitwise Operations
with ALUCntl select
ALU_Result <= add_result(31 downto 0) when "0010", --Add
sub_result(31 downto 0) when "0110", --sub
A AND B when "0000",
A OR B when "0001",
A XOR B when "0011",
A NOR B when "1100",
A when others; ---condition for all other alu control signals
ALUOut <= ALU_Result;
-- Addition Operation and carry out generation
a32 <= '0' & A;
b32 <= '0' & B;
c32(0) <= Carryin;
add_result <= a32 + b32 + c32;
sub_result <= a32 - b32;
-- Unsigned addition
with ALUCntl select
add_result <= std_logic_vector(unsigned(A_u) + unsigned(B_u) + unsigned(Carryin)) when "0010",
std_logic_vector(unsigned(A_u) + unsigned(B_u)) when "0101",
(others => '0') when others;
ALU_Result <= add_result(31 downto 0);
-- Unsigned subtraction
sub_result <= std_logic_vector(unsigned(A_u) - unsigned(B_u));
ALU_Result <= sub_result(31 downto 0) when ALUCntl = "0100" else ALU_Result;
-- Zero flag
Zero <= '1' when ALU_Result = x"00000000" else '0';
-- Overflow flag
add_ov <= (A(31) and B(31) and (not ALU_Result(31))) or ((not A(31)) and (not B(31)) and ALU_Result(31));
sub_ov <= (A(31) and (not B(31)) and (not ALU_Result(31))) or ((not A(31)) and B(31) and ALU_Result(31));
with ALUCntl select
Overflow <= add_ov when "0010",
sub_ov when "0110",
'Z' when others;
-- Carryout
with ALUCntl select
Carryout <= add_result(32) when "0010",
sub_result(32) when "0110",
'Z' when others;
process (ALUCntl, A, B)
begin
-- Signed SLT
if (ALUCntl = "1001") then
if (signed(A) < signed(B)) then
ALU_Result <= "00000001"; -- set ALU output to 1 if A < B
else
ALU_Result <= "00000000"; -- set ALU output to 0 if A >= B
end if;
end if;
-- Unsigned SLT
if (ALUCntl = "1010") then
if (unsigned(A) < unsigned(B)) then
ALU_Result <= "00000001"; -- set ALU output to 1 if A < B
else
ALU_Result <= "00000000"; -- set ALU output to 0 if A >= B
end if;
end if;
end process;
end Behavioral;
I think
答案1
得分: 3
以下是翻译好的部分:
问题在于CarryIn
只是一个单独的std_logic
,但使用signed
或unsigned
进行算术运算需要它成为一个数组的一部分。你不能简单地将枚举类型如std_logic
转换为数组,你必须从中创建一个数组聚合,这样做特别容易,因为unsigned
或signed
只是std_logic
的数组,就像std_logic_vector
一样。这里有几个选项:
- 使用数组聚合分配
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (0=>Carryin));
这样做是因为你将CarryIn
分配给数组的第0位,编译器知道它必须是unsigned
,因为它是一个+
函数的一部分。
- 与一个空数组连接
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (""&Carryin));
因为VHDL允许空数组,""只是一个长度为0的位字符串文字,现在编译器知道它可以创建一个数组,然后根据上下文知道它是无符号的。
- 使用临时信号
可能比较复杂,但也是可以的:
signal cin_a : unsigned(0 downto 0);
cin_a(0) <= CarryIn;
std_logic_vector(unsigned(A_u) + unsigned(B_u) + cin_a)
再次强调,现在你知道它是无符号的。
英文:
The problem is that CarryIn
is simply a single std_logic
, but arithmatic with signed
or unsigned
requires it to be part of an array. You simply cannot convert an enumerated type like std_logic
into an array, you have to create an array aggregate from it, and it is particularly easy because unsigned
or signed
are simply arrays of std_logic
like std_logic_vector
. There are several options here:
- Use an aggregate assignment
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (0=>Carryin));
This works because you are assigning CarryIn
to bit 0 of an array, and the compiler knows it must be unsigned
because of the context of being part of a "+"
function
- Concatenate with a null array.
std_logic_vector(unsigned(A_u) + unsigned(B_u) + (""&Carryin));
Because VHDL allows null arrays, and "" is simply a 0 length bit string literal, it now knows it can create an array, and then it knows it is unsigned from the context.
- Use a temporary signal
probably the most involved, but is fine:
signal cin_a : unsigned(0 downto 0);
cin_a(0) <= CarryIn;
std_logic_vector(unsigned(A_u) + unsigned(B_u) + cin_a)
Again, now you know it is an unsigned.
答案2
得分: -1
我猜问题出在携带部分,只有1位,所以将其转换为无符号或有符号都没有意义。
英文:
i guess it's the carryin that cause problem, it's just 1bit so doesn't make sens to convert it to either unsigned or signed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论