jp48
jp48

Reputation: 1366

VHDL: analogous to Verlilog syntax for describing an adder

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

Answers (2)

Renaud Pacalet
Renaud Pacalet

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

Oldfart
Oldfart

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

Related Questions