0
\$\begingroup\$

I am trying to design a full subtractor in SystemVerilog.

I searched on Wikipedia and I found this https://en.wikibooks.org/w/index.php?title=Microprocessor_Design/Add_and_Subtract_Blocks

module full_adder(a, b, cin, cout, s);
   input a, b, cin;
   output cout, s;
   wire temp;
   temp = a ^ b;
   s = temp ^ cin;
   cout = (cin & temp) | (a & b);
endmodule

But this code seems quite lengthy, and works for only the 1-bit case. I am thinking of taking the 2's complement of the second operand to do subtraction, but that would work only for the 1-bit case. 2's complement is by applying the bitwise negation (~) operator and adding 1 to it.

But this won't be reusable since it works only for the 1-bit case. Is there a more reusable approach?

\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

Sure, but you don't need to.

Just write

a - b

wherever you would instantiate the full substractor. Your code will be more readable and synthesis hasn't had difficulties with this construct since the 90s.

\$\endgroup\$
0
2
\$\begingroup\$

If you actually want to do addition or subtraction then use the built-in + and - operators, that is what they are there for.

Still if we want to design a multi-bit adder from first principles, we can do it by operating on vectors. So we essentially build a bunch of 1 bit adders in paralell, then wire them up to each other.

module full_adder(a, b, cin, cout, s);
   parameter width;
   input [width-1:0] a;
   input [width-1:0] b;
   input cin;

   output cout;
   output [width-1:0] s;   
   wire [width-1:0] temp;
   wire [width-1:0] cininternal;
   wire [width-1:0] coutinternal;
   wire [widht-1:0] sinternal;

   assign cininternal[0] = cin;
   assign cininternal[width-1:1] = coutinternal[widht-2:0];

   assign temp = a ^ b;
   assign s = temp ^ cininternal;
   assign coutinternal = (cininternal & temp) | (a & b); 

   assign cout = coutinternal[width-1];

endmodule

To make a subtractor instead of an adder we just invert the second input and invert the carry in and carry out.

module full_subtractor(a, b, cin, cout, s);
   parameter width;
   input [width-1:0] a;
   input [width-1:0] b;
   input cin;

   output cout;
   output [width-1:0] s;   
   wire [width-1:0] temp;
   wire [width-1:0] cininternal;
   wire [width-1:0] coutinternal;
   wire [widht-1:0] sinternal;

   assign cininternal[0] = ~cin;
   assign cininternal[width-1:1] = coutinternal[widht-2:0];

   assign temp = a ^ (~b);
   assign s = temp ^ cininternal;
   assign coutinternal = (cininternal & temp) | (a & (~b)); 

   assign cout = ~coutinternal[width-1];

endmodule
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.