Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

2's complement in verilog

Status
Not open for further replies.

sindrig

Newbie level 2
Joined
Feb 25, 2010
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Iceland
Activity points
1,302
Hey guys,
I have this project for school and i'm getting really frustrated with it. I'm supposed to create a circuit that can add or reduct one 4-bit number from another using full-adders that use half-adders. I've managed to make it work with addition but reduction's a bit more complicated. I have number A = A3'A2'A1'A0 and number B = B3'B2'B1'B0. My best guess this far is to make wires that take values from B and then use if-statements to get it's 2's complement and then add those two numbers together.
Here's my code so far:

Code:
`timescale 1ns / 1ps
module samlagning_fradrattur(A0, A1, A2, A3, B0, B1, B2, B3, S0, S1, S2, S3, M);
    input A0, A1, A2, A3;
	 input B0, B1, B2, B3;
	 reg BB0, BB1, BB2, BB3, C0;
	 input M;
	 output wire S0, S1, S2, S3;
	 wire C1, C2, C3, overflow;
	 
	 initial 
	 begin
	 assign C0 = 0;
	 assign BB0 = B0;
	 assign BB1 = B1;
	 assign BB2 = B2;
	 assign BB3 = B3;
  			if(M==1)
				begin
				assign BB0 =~BB0;
  				assign BB1 =~BB1;
  				assign BB2 =~BB2;
  				assign BB3 =~BB3;
  				if(BB0==0)
  					assign BB0 =~BB0;
				else if(BB1==0)
						begin
						assign BB0 =~BB0;
						assign BB1=~BB1;
						end
					else if(BB2==0)
							begin
							assign BB0 =~BB0;
							assign BB1 =~BB1;
							assign BB2 =~BB2;
							end
						else if(BB3==0)
								begin
								assign BB0 =~BB0;
								assign BB1 =~BB1;
								assign BB2 =~BB2;
								assign BB3 =~BB3;
								end
				end
end

		full_adder F0(A0, BB0, C0, S0, C1);
		full_adder F1(A1, BB1, C1, S1, C2);
		full_adder F2(A2, BB2, C2, S2, C3);
		full_adder F3(A3, BB3, C3, S3, overflow);			


endmodule

The problem is that even though M==1 none of the BB* regs seem to change their values. Say, if I have A = 0100 and B = 0011 and M = 1, the output S becomes 0111.
If you spot were I went wrong please share it, I'm getting pretty frustrated googling and reading my textbook for an answer :D

BR,
Sindri

Added after 54 minutes:

OK, so i found out probably the biggest flaw; i need an infinite loop to check for M==1, not just at the initial. So my code now looks like this:

Code:
`timescale 1ns / 1ps
module samlagning_fradrattur(A0, A1, A2, A3, B0, B1, B2, B3, S0, S1, S2, S3, M);
    input A0, A1, A2, A3;
	 input B0, B1, B2, B3;
	 reg BB0, BB1, BB2, BB3, C0;
	 input M;
	 output wire S0, S1, S2, S3;
	 wire C1, C2, C3, overflow;
	 
	initial 
		begin
		assign C0 = 0;
		assign BB0 = B0;
		assign BB1 = B1;
		assign BB2 = B2;
		assign BB3 = B3;
		end
		
	initial forever
		begin
  			if(M==1)
				begin
				assign BB0 =~BB0;
  				assign BB1 =~BB1;
  				assign BB2 =~BB2;
  				assign BB3 =~BB3;
  				if(BB0==0)
  					assign BB0 =~BB0;
				else if(BB1==0)
						begin
						assign BB0 =~BB0;
						assign BB1=~BB1;
						end
					else if(BB2==0)
							begin
							assign BB0 =~BB0;
							assign BB1 =~BB1;
							assign BB2 =~BB2;
							end
						else if(BB3==0)
								begin
								assign BB0 =~BB0;
								assign BB1 =~BB1;
								assign BB2 =~BB2;
								assign BB3 =~BB3;
								end
				end
			#20;
end

		full_adder F0(A0, BB0, C0, S0, C1);
		full_adder F1(A1, BB1, C1, S1, C2);
		full_adder F2(A2, BB2, C2, S2, C3);
		full_adder F3(A3, BB3, C3, S3, overflow);			


endmodule

The thing now is that when M==1 the output S becomes the 2's complement of B?!? (that is, if B=0110, S becomes 1010) Has anyone got an idea about why that could be? I'm attaching the full_adder.v, half_adder.v and my testbench codes also, maybe someone can find out why this is happening...

Code:
//full_adder.v
`timescale 1ns / 1ps
module full_adder(input A, B, Cin, output wire S, Cout);
	wire S0, C0, C1;
	 
	half_adder H0(A,B,S0,C0);
	half_adder H1(S0,Cin,S,C1);
	or (Cout, C0, C1);

endmodule

Code:
//half_adder.v
`timescale 1ns / 1ps
module half_adder(input A, B, output wire S, Cout);
	
	assign S = A^B;
	assign Cout = A&B;

endmodule

Code:
//prufbekkur.v
`timescale 1ns / 1ps
module prufbekkur();
	reg A0, A1, A2, A3, B0, B1, B2, B3, M;
	wire S0, S1, S2, S3;
	
	samlagning_fradrattur uut(A0, A1, A2, A3, B0, B1, B2, B3, S0, S1, S2, S3, M);
	initial begin
		A0 = 0; A1 = 0; A2 = 0; A3 = 0; B0 = 0; B1 = 0; B2 = 0; B3 = 0; M = 0; #100;
		end
		always #20 B0=~B0;
		always #40 B1=~B1;
		always #80 B2=~B2;
		always #160 B3=~B3;
		always #320 A0=~A0;
		always #640 A1=~A1;
		always #1280 A2=~A2;
		always #2560 A3=~A3;
		always #5120 M=~M;


endmodule

Again, any help is appreciated ;)

BR,
Sindri
 

Hello,
Your main problem is that you are trying to use initial blocks to model combinational logic. Initial blocks are not synthesizable and therefore should not be used to design any actual circuits. You should try moving this into an always block. The simple way to take a twos complement in verilog is to invert and add 1. For instance: assign TwoComp = ~Orignal + 1. If you are restricted to using full adder modules and not the verilog addition operator, simply feed the inverted signal in as 1 input to a full adder and harcode the other input to 1. The output will be the two's complement.

Here is an example of a 4 bit subtractor in verilog.
**broken link removed**
 

Hi,
I figured that out just before your post. I've also looked over your link and will try to implement something from it into my project.
But have you got an idea for why my sum now (see above) becomes the 2's complement of B?

Best regards,
Sindri
 

Hi Sindri,
Just looking at your code it is very difficult to see what you are trying to do. Like I said before, the initial block with the hard coded delay in it is not the correct way to structurally model a combinational circuit. If you have experience with logic circuits, you need to think of this code as a description of these circuits, not as a programming language.

So, for example, a loop in your circuit description would not represent code that executes multiple times like it would in a CPU. A loop would just be used to expand repeated logic in a more concise manner.

Hope that helps.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top