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.

can somebody help me out with verilog

Status
Not open for further replies.

samcheetah

Advanced Member level 2
Joined
May 25, 2004
Messages
645
Helped
39
Reputation
78
Reaction score
10
Trophy points
1,298
Location
Pakistan
Activity points
6,916
i have written a small code in verilog and it seems to be not working. the aim is to build a logic block that would AND or OR two inputs depending upon a third control input. actually im debugging a code for an ALU that would ADD or SUBTRACT depending upon a control input but i think im doing something wrong in the always and if blocks so if someone can point my mistake in this code, i can debug the original code im working on.

Code:
module and_or( out, in1, in2, ctrl );

output out;
input in1, in2, ctrl;

reg out;

always @(in1 or in2 or ctrl)
begin

	if(ctrl)
		and (out, in1, in2);
	else
		or (out, in1, in2);
end

endmodule

module stimulus;

reg IN1, IN2;
reg CTRL;
wire OUT;

and_or MOD(OUT, IN1, IN2, CTRL);

initial
begin
  $monitor($time," IN1= %b, IN2=%b, CTRL = %b, --- OUT= %b\n",
                          IN1, IN2, CTRL, OUT);
end

// Stimulate inputs
initial
begin
  IN1 = 1'b1; IN2 = 1'b0; CTRL = 1'b0;

  #5 IN1 = 1'b1; IN2 = 1'b0; CTRL = 1'b1;

end

endmodule

EDIT: one thing i forgot to mention is that i am working on the gate-level
 

I've never done gate-level design, but I think I see several problems.
1. You can't instantiate modules (such as 'and' and 'or') inside an 'if' statement.
2. You connected multiple outputs to one reg.
3. Using 'always' and 'if' seems inconsistent with doing gate-level design.

How about doing something like this (my first gate-level attempt)?

Code:
module and_or (out, in1, in2, ctrl);
  input  in1, in2, ctrl;
  wire   pctrl, nctrl, and_out, or_out;
  output out;

  and  and1 (and_out, in1, in2);
  or   or1  (or_out, in1, in2);
  buf  buf1 (pctrl, ctrl);
  not  not1 (nctrl, ctrl);
  cmos sw1  (out, and_out, pctrl, nctrl);
  cmos sw2  (out, or_out,  nctrl, pctrl);
endmodule

That was painful. I suppose I could have used gates instead of switches.

How about doing this instead?

Code:
module and_or (out, in1, in2, ctrl);
  input  in1, in2, ctrl;
  output out;
  assign out = ctrl ? (in1 & in2) : (in1 | in2);
endmodule
 

1. You can't instantiate modules (such as 'and' and 'or') inside an 'if' statement.

yeah, you can say that again. i learnt it the hard way :D

actually i am only allowed to use the gate-level approach so i cant think of anything else. anyway i tried to solve the problem in the following way and it worked.

Code:
module and_or( out, in1, in2, ctrl );

output out;
input in1, in2, ctrl;

reg out;
wire d1, d2;

and (d1, in1, in2);
or (d2, in1, in2);

always @(in1 or in2 or ctrl)
begin

	if(ctrl)
		assign out = d1;
	else
		assign out = d2;
end

endmodule

okay i know if i use the same strategy with my original adder/subtractor design i would be using too much of silicon area and my design wouldnt be efficient. but it works!! and i wasnt required to create an efficient piece of code anyway!
 

I think 'if' and 'reg' would be unacceptable in a gate-level-only design.
Just a hunch, I'm not sure.
 

    samcheetah

    Points: 2
    Helpful Answer Positive Rating
If you want only gate level and no if statements then try this code:
Code:
module and_or( out, in1, in2, ctrl );

output out;
input in1, in2, ctrl; 

wire d1, d2, d3, d4, ctl_n, out;

assign ctl_n = ~ ctl;

and (d1, in1, in2); 
or(d2, in1, in2);
and(d3, ctl, d1);
and(d4, ctl_n, d2);
or(out, d3, d4);

endmodule
 

    samcheetah

    Points: 2
    Helpful Answer Positive Rating
i think at gate level there should not appear behavioral statement like always etc.
i agree with adap
 

    samcheetah

    Points: 2
    Helpful Answer Positive Rating
thanx adap. i understood your code easily but ill try to implement this with the original problem i had.
 

Hi samcheetah,

1)
assign is only allowed outside of procedural blocks, and only to signals of wire types. To use a signal on the left_hand_sides of an assignment in a procedural
block, you must define it as register type.

2)
for gate level, i think there are only instances of library gates included in the modules, with no behaviour descriptions.
 

    samcheetah

    Points: 2
    Helpful Answer Positive Rating
thanx rprince006. the answer to your first part is that now i wont be using assign because i am going to implement a total gate level design. but there is one question that i have.

adap has "gated" the outputs of both the and and or gates so as to control which output will be available outside. now in my original design the output is a 4-bit sum or difference depending upon a control signal. now, should i "gate" the outputs or should i "gate" the inputs to the sum and difference part? i know most of you wont understand my question because you cant see my code. ill upload it when im done converting it into a total gate-level implementation. but generally what should be done?

ill try to come up with a solution and ill let you guys know about it.
 

Hi samcheetah,

I don't know if I understood your question, but I'll try to analyse.
If you have in1[3:0] and in2[3:0] as inputs then you make an adder and a subtactor (at gate level) and you have d1[3:0] and d2[3:0] as results.
Each bit of d1 and the ctl go to and gates. So you will have 4 outputs d3[3:0].
Each bit of d2 and the opposite of ctl (~ctl) go to and gates. So you will have 4 outputs d4[3:0].
Each bit of d3 is input to an or gate with the equivalent bit of d4. That means d3[3] with d4[3] , d3[2] with d4[2] and so on. That will produce the out[3:0] signal.
Hope it's clear.
 

    samcheetah

    Points: 2
    Helpful Answer Positive Rating
i thought about doing it the way you have said adap. but i would have had to use alot of gates. actually the 4-bit adder/subtractor unit was made from 1-bit adders and subtractors. so i thought that if i "gated" the inputs to the 1-bit adder and subtractor modules i would use lesser gates and still acheive what i wanted.

i tried to write code with keeping this in mind but it just got too complex. then i figured out a completely diffferent approach to this problem. i made a 4-bit adder which did both the addition and subtraction depending upon the carry-in. when the carry-in is high, the second input is 2's complemented so the result is the difference between the two inputs.

this approach reduced the lines of code and made it really simple. i the following is my initial design

Code:
/*******************************************************************

                         3-Input AND Gate

*******************************************************************/

module and3( d, a, b, c );
	output d;
	input a,b,c;
	wire dummy;
	and (dummy,a,b);
	and (d,dummy,c);
endmodule

/*******************************************************************

                          3-Input OR Gate

*******************************************************************/

module or3( d, a, b, c );
	output d;
	input a,b,c;
	wire dummy;
	or (dummy,a,b);
	or (d,dummy,c);
endmodule

/*******************************************************************

                          4-Input OR Gate

*******************************************************************/

module or4( e, a, b, c, d );
	output e;
	input a,b,c,d;
	wire dummy;
	or3 G(dummy,a,b,c);
	or (e,dummy,d);
endmodule

/*******************************************************************

                         1-Bit Full Adder

*******************************************************************/
module fulladd(sum, c_out, a, b, c_in);

	// Input and output port declarations (Interface)
	output sum, c_out;
	input a, b, c_in;

	// Dummy wires (Internals)
	wire s1, c1, c2;

	// Instantiation of logic gate primitives
	xor (s1, a, b);
	and (c1, a, b);

	xor (sum, s1, c_in);
	and (c2, s1, c_in);

	xor  (c_out, c2, c1);

endmodule

/*******************************************************************

                        4-Bit Full Adder

*******************************************************************/

module fulladd4(sum, c_out, a, b, c_in);

	// Input and output port declarations (Interface)
	output [3:0] sum;
	output c_out;
	input[3:0] a, b;
	input c_in;

	// Dummy wires (Internals)
	wire c1, c2, c3;

	// Instantiate four 1-bit full adders.
	fulladd fa0(sum[0], c1, a[0], b[0], c_in);
	fulladd fa1(sum[1], c2, a[1], b[1], c1);
	fulladd fa2(sum[2], c3, a[2], b[2], c2);
	fulladd fa3(sum[3], c_out, a[3], b[3], c3);

endmodule

/*******************************************************************

                       1-Bit Full Subtractor

*******************************************************************/

module fullsub(diff, b_out, a, b, b_in);

	//Output and Input  ports (Interface)
	output diff, b_out;
	input a, b, b_in;

	//Dummy wires (Internals)
	wire an,bn,b_inn,d1,d2,d3,d4,d5,d6,d7; 

	//Complemented inputs
	not (an,a);
	not (bn,b);
	not (b_inn,b_in);

	//Computation of the difference and borrow out
	and3 D1(d1,an,bn,b_in);
	and3 D2(d2,an,b,b_inn);
	and3 D3(d3,a,bn,b_inn);
	and3 D4(d4,a,b,b_in);
	or4 DIFF(diff,d1,d2,d3,d4);

	and (d5,an,b);
	and (d6,an,b_in);
	and (d7,b,b_in);
	or3 B_OUT(b_out,d5,d6,d7);

endmodule

/*******************************************************************

                       4-Bit Full Subtractor

*******************************************************************/

module fullsub4(diff, b_out, a, b, b_in);

	// I/O port declarations
	output [3:0] diff;
	output b_out;
	input[3:0] a, b;
	input b_in;

	// Internal nets
	wire b1, b2, b3;

	// Instantiate four 1-bit full adders.
	fullsub fs0(diff[0], b1, a[0], b[0], b_in);
	fullsub fs1(diff[1], b2, a[1], b[1], b1);
	fullsub fs2(diff[2], b3, a[2], b[2], b2);
	fullsub fs3(diff[3], b_out, a[3], b[3], b3);

endmodule

/*******************************************************************

                      Adder/Subtractor Unit

*******************************************************************/

module addsub(result, cb_out, a, b, ctrl);

	output [3:0] result; //4-bit sum/difference
	output cb_out;       //carry/borrow out
	input [3:0] a,b;     //4-bit inputs
	input ctrl;          //if ctrl is high, the module will add
                             //the inputs and if ctrl is low, the
                             //module will subtract the inputs

	reg [3:0] result;
	reg cb_out;

	wire cb_in = 1'b0;   //initial carry/borrow is zero
	wire [3:0] d1, d2;
	wire c_out, b_out;

	fulladd4 ADD(d1, c_out, a, b, cb_in);
	fullsub4 SUB(d2, b_out, a, b, cb_in);


	always @(a or b or ctrl)
	begin
		if(ctrl)
			begin
				assign result = d1;
				assign cb_out = c_out;
			end
		else
			begin
				assign result = d2;
				assign	cb_out = b_out;
			end
	end

endmodule

/*******************************************************************

                    Test Bench for the Adder

*******************************************************************/

module stimulus;

	// Set up variables
	reg [3:0] A, B;
	reg CTRL;
	wire [3:0] RESULT;
	wire CB_OUT;

	// Instantiation of the 4-bit adder/subtractor we made
	addsub alu(RESULT, CB_OUT, A, B, CTRL);


	// Settin up the monitoring for the signal values
	initial
	begin
  	$monitor($time," A= %b, B=%b, CTRL=%b --- CB_OUT= %b, RESULT= %b\n",
                 A, B, CTRL, CB_OUT, RESULT);
	end

	// Stimulation of the inputs
	initial
	begin
   		A = 4'd1; B = 4'd1; CTRL = 1'b1;
   
   		#5 A = 4'd2; B = 4'd2; CTRL = 1'b1;

  		#5 A = 4'd8; B = 4'd8; CTRL = 1'b1;

   		#5 A = 4'd2; B = 4'd1; CTRL = 1'b0;

   		#5 A = 4'd1; B = 4'd2; CTRL = 1'b0;

   		#5 A = 4'd9; B = 4'd6; CTRL = 1'b0;
	end

endmodule

/*******************************************************************

                              END

*******************************************************************/

and here is the final design

Code:
/*******************************************************************

                        1-Bit Full Adder

*******************************************************************/

module fulladd(sum, c_out, a, b, c_in);

output sum, c_out;
input a, b, c_in;

wire s1, c1, c2;

xor (s1, a, b);
and (c1, a, b);

xor (sum, s1, c_in);
and (c2, s1, c_in);

xor  (c_out, c2, c1);

endmodule

/*******************************************************************

                   4-Bit Full Adder/Subtractor

*******************************************************************/

module addsub(result, c_out, ovrfl, a, b, c_in);

output [3:0] result;
output c_out, ovrfl;
input[3:0] a, b;
input c_in; //when c_in is low, the inputs are added and when c_in
            //is high, the inputs are subtracted

wire c1, c2, c3, b3, b2, b1, b0;

xor (b3, b[3], c_in);
xor (b2, b[2], c_in);
xor (b1, b[1], c_in);
xor (b0, b[0], c_in);

fulladd fa0(result[0], c1, a[0], b0, c_in);
fulladd fa1(result[1], c2, a[1], b1, c1);
fulladd fa2(result[2], c3, a[2], b2, c2);
fulladd fa3(result[3], c_out, a[3], b3, c3);

xor (ovrfl, c_out, c3);

endmodule

/*******************************************************************

                            Test Bench

*******************************************************************/

module stimulus;

reg [3:0] A, B;
reg C_IN;
wire [3:0] RESULT;
wire C_OUT, ovrfl;

addsub ALU(RESULT, C_OUT, OVRFL, A, B, C_IN);

initial
begin
  $monitor($time," A= %b, B=%b, C_IN= %b, --- C_OUT= %b, OVRFL= %b, RESULT= %b\n",
                          A, B, C_IN, C_OUT, OVRFL, RESULT);
end

initial
begin
  A = 4'd1; B = 4'd1; C_IN = 1'b0;

  #5 A = 4'd1; B = 4'd1; C_IN = 1'b1;

  #5 A = 4'd4; B = 4'd3; C_IN = 1'b0;

  #5 A = 4'd4; B = 4'd3; C_IN = 1'b1;
end

endmodule

/*******************************************************************

                                 END

*******************************************************************/

thanx everyone for helping me all the way.

and ill be waiting for comments on the code
 

Hi samcheetah, nice thought the second code.
I have just a question about it.
What's the purpose of overfl signal. It's zero in the cases that the testbench tested. And about c_out which is the carry out signal.
Do you concatenate it with the result when addition operation is selected? And what about when subtraction takes place? In the cases of the testbench is one when in subtaction. Do you throw it away?
 

hi adap im sorry for replying late, actually my ISP was having some problems

the overflow is actually xor of carry from the third adder and the carry from the fourth adder. this will indicate an overflow as in the case of two big numbers being added together (e.g. 4'd10 + 4'd10).

the carry out signal indicates the carry of the last adder (4th adder). in the case of subtraction the carry out will be 1 if the result is positive and vice versa. and in the case of addition it will act just like a normal carry out will do.

subtraction will take place when carry in is 1 and addition will take place when carry in is 0. so that assumes that in the case of addition the initial carry is always zero, which is mostly the case. when the carry in is 1, the xor gates complement the second input and add 1 and add the first input to it. so the operation A-B is converted into A + B` + 1
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top