Reputation: 1366
I'm trying to replicate this shortcut for easily generating an adder while separating the output carry and the result:
reg [31:0] op_1;
reg [31:0] op_2;
reg [31:0] sum;
reg carry_out;
always @(posedge clk)
{ carry_out, sum } <= op_1 + op_2;
In my case, it's Ok to use the nonstandard ieee.STD_LOGIC_UNSIGNED
.
I would prefer not to use VHDL-2008 features as I am stuck with Xilinx ISE, at the moment.
Upvotes: 0
Views: 65
Reputation: 29345
Too bad that VHDL 2008 is not an option. If it was, the following would make it:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
port(
clk: in std_ulogic;
a, b: in u_unsigned(31 downto 0);
s: out u_unsigned(31 downto 0);
co: out std_ulogic
);
end entity foo;
architecture rtl of foo is
begin
process(clk)
begin
if rising_edge(clk) then
(co, s) <= ('0' & a) + ('0' & b);
end if;
end process;
end architecture rtl;
But as you are stuck with older versions, the following should work:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
port(
clk: in std_ulogic;
a, b: in unsigned(31 downto 0);
s: out unsigned(31 downto 0);
co: out std_ulogic
);
end entity foo;
architecture rtl of foo is
begin
process(clk)
variable tmp: unsigned(32 downto 0);
begin
if rising_edge(clk) then
tmp := ('0' & a) + ('0' & b);
s <= tmp(31 downto 0);
co <= tmp(32);
end if;
end process;
end architecture rtl;
Upvotes: 2
Reputation: 6269
You have to extend op_1, op_2 to 33 bits (Adding a zero at the top as the numbers are unsigned, for signed values you would replicate the top bit). The result (sum) also must be 33 bits.
Do a normal 33+33 bit addition (with all the conversions in VHDL).
Then split off the sum[32] as the carry.
Upvotes: 1