Google Answers Logo
View Question
 
Q: Verilog multiplier BOOTH'S ALGORITHM ( Answered 5 out of 5 stars,   0 Comments )
Question  
Subject: Verilog multiplier BOOTH'S ALGORITHM
Category: Computers > Programming
Asked by: motts786-ga
List Price: $50.00
Posted: 07 May 2005 17:08 PDT
Expires: 06 Jun 2005 17:08 PDT
Question ID: 519016
I need a Verilog behavioral code for:
(1) signed 16 bit multiplication. The product is 16-bits and the
multiplier and multiplicand are each 8 bits. Using Booths algorithm.
the module definition is as follows. 

module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q;
reg Q_1;
reg [3:0] count;


start: positivee pulse, it starts a new multiply operation and has a
five-time-unit duration;
positive edge of it coincides with negative edge of clock


clarification on 'A' Q and Q_1:

the multiplier and multiplicand are placed in the Q and
M registers, respectively. There is also a 1-bit register placed
logically to the right of the
least significant bit (Q0) of the Q register and designated Q-1; its
use is explained shortly.
The results of the multiplication will appear in the A and Q
registers. A and Q-1 are
initialized to 0. As before, control logic scans the bits of the
multiplier one at a time.
Now, as each bit is examined, the bit to its right is also examined.
If the two bits are the
same (1-1 or 0-0), then all of the bits of the A, Q, and Q-1 registers
are shifted to the right
1 bit. If the two bits differ, then the multiplicand is added to or
subtracted from the A
register, depending on whether the two bits are 0-1 or 1-0. Following
the addition or
subtraction, the right shift occurs. In either case, the right shift
is such that the leftmost bit
of A, namely An-1, not only is shifted into An-2, but also remains in
An-1. This is required
to preserve the sign of the number in A and Q. It is known as an
arithmetic shift, because
it preserves the sign bit.

Clarification of Question by motts786-ga on 07 May 2005 17:15 PDT
I need this done by MAY 10, 2005 at the LATEST. Please help
Thank you

Clarification of Question by motts786-ga on 07 May 2005 22:14 PDT
I forgot to include this in the specs but this should also include an
Adder/Subtractor module that performs the necessary additions and
subtractions.
Thank You
Answer  
Subject: Re: Verilog multiplier BOOTH'S ALGORITHM
Answered By: studboy-ga on 08 May 2005 00:40 PDT
Rated:5 out of 5 stars
 
OK, I still cannot view the links you post on geocities, so I'm going
to assume a testbench (and give you for FREE--see below).  I also post
the simulation results--please run it yourself to view the results (I
cannot post waveforms here, and you will need to run it with your
simulator over there anyway).

The following is "implied structural"--I believe this is adequate. 
Since we have this done early, you can email/check with the
authorities to see if this version is OK--I believe this implementing
in dff is redundant and unnecessary--if needed you can tell from the
other example it's trivial to convert it and I will be happy to post a
conversion, but please check first as this can save both of us time
(and money :)

-------------------------------------------------------------------------------


module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q, M;
reg Q_1;
reg [3:0] count;

wire [7:0] sum, difference;

always @(posedge clk)
begin
   if (start) begin
      A <= 8'b0;      
      M <= mc;
      Q <= mp;
      Q_1 <= 1'b0;      
      count <= 4'b0;
   end
   else begin
      case ({Q[0], Q_1})
         2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
         2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
         default: {A, Q, Q_1} <= {A[7], A, Q};
      endcase
      count <= count + 1'b1;
   end
end

alu adder (sum, A, M, 1'b0);
alu subtracter (difference, A, ~M, 1'b1);

assign prod = {A, Q};
assign busy = (count < 8);

endmodule

//The following is an alu.  
//It is an adder, but capable of subtraction:
//Recall that subtraction means adding the two's complement--
//a - b = a + (-b) = a + (inverted b + 1)
//The 1 will be coming in as cin (carry-in)
module alu(out, a, b, cin);
output [7:0] out;
input [7:0] a;
input [7:0] b;
input cin;

assign out = a + b + cin;

endmodule

module testbench;

reg clk, start;
reg [7:0] a, b;

wire [15:0] ab;
wire busy;

multiplier multiplier1(ab, busy, a, b, clk, start);

initial begin
clk = 0;
$display("first example: a = 3 b = 17");
a = 3; b = 17; start = 1; #50 start = 0;
#80 $display("first example done");
$display("second example: a = 7 b = 7");
a = 7; b = 7; start = 1; #50 start = 0;
#80 $display("second example done");
$finish;
end

always #5 clk = !clk;

always @(posedge clk) $strobe("ab: %d busy: %d at time=%t", ab, busy, $stime);

endmodule

Clarification of Answer by studboy-ga on 08 May 2005 00:41 PDT
Output:


first example: a = 3 b = 17
ab:    17 busy: 1 at time=                   5
ab:    17 busy: 1 at time=                  15
ab:    17 busy: 1 at time=                  25
ab:    17 busy: 1 at time=                  35
ab:    17 busy: 1 at time=                  45
ab: 65160 busy: 1 at time=                  55
ab:   196 busy: 1 at time=                  65
ab:    98 busy: 1 at time=                  75
ab:    49 busy: 1 at time=                  85
ab: 65176 busy: 1 at time=                  95
ab:   204 busy: 1 at time=                 105
ab:   102 busy: 1 at time=                 115
ab:    51 busy: 0 at time=                 125
first example done
second example: a = 7 b = 7
ab:     7 busy: 1 at time=                 135
ab:     7 busy: 1 at time=                 145
ab:     7 busy: 1 at time=                 155
ab:     7 busy: 1 at time=                 165
ab:     7 busy: 1 at time=                 175
ab: 64643 busy: 1 at time=                 185
ab: 65089 busy: 1 at time=                 195
ab: 65312 busy: 1 at time=                 205
ab:   784 busy: 1 at time=                 215
ab:   392 busy: 1 at time=                 225
ab:   196 busy: 1 at time=                 235
ab:    98 busy: 1 at time=                 245
ab:    49 busy: 0 at time=                 255
second example done

Clarification of Answer by studboy-ga on 08 May 2005 00:44 PDT
I found a slight error in the code--I'm currently debugging it and
will post a correction tomorrow.

Clarification of Answer by studboy-ga on 08 May 2005 01:30 PDT
Nevermind what I said a few minutes ago--the code is correct.  The
range of stimulus is 0-127: since the uppermost bit[8] is a sign bit.

Clarification of Answer by studboy-ga on 08 May 2005 02:55 PDT
OK, your geocities acct is finally accessible--
I made a couple of lines changes--here's the testbench:

module test_Booth_8;
  reg [7:0] MC, MP;
	reg [15:0] Correct;
  reg Clk, Start;
	reg Error;
	integer	Tot_errors, Cycles;
  integer J,K;  
  wire [15:0] Prod;
  wire Busy;
  parameter Del = 5;

// Stopwatch
  initial begin
  #9000000 $finish;
  end

// Clock generator
	initial begin Clk = 0; forever #Del Clk = ~Clk; end

/* Initialize certain startup variables. 
Loop and generate potentially exhaustive sequence
of multiplier and multiplicand values.
Gather data about any incorrect products that might be calculated. */

	initial begin
		Start = 0;
		Tot_errors = 0;
		Cycles = -2;
		#(2*Del) for (K=127; K>=-127; K=K-1) begin
			for (J=127;J>=-127; J=J-1) begin
				MC = K;
				MP = J;
				Correct = K*J;
				Error = 0;
				@(posedge Clk) Start = 1;
				#Del Start = 1'b0;
				@(negedge Busy) if (Correct-Prod) Error = 1;
				Tot_errors = Tot_errors + Error;
				check (Correct);
				end
			end 
		end

/* Calculate number of cycles to perform each multiplication. The value -2 
compensates for extra cycles that are included in the count.*/

	always @ (posedge Clk or Busy) begin
		if(Busy) Cycles = Cycles + 1;
		else #1 Cycles = -2;
		end
// Print information about each product calculated.

  task check;
    input [15:0] Correct;
    $display ("Time = %5d, Cycles = %2d, MC = %h, MP = %h, Prod = %h,
Correct prod = %h, Error = %h, T_Errors = %0d",
					$time, Cycles, MC, MP, Prod, Correct, Error, Tot_errors);
  endtask

// Module instances
multiplier B8 (Prod, Busy, MC, MP, Clk, Start);

endmodule


-----------------------


simulation result (last line) shows zero errors:

Time =              8999830, Cycles =           6, MC = bb, MP = 6d, Prod = e29f
, Correct prod = e29f, Error = 0, T_Errors =           0
L104 "multiplier.v": $finish at simulation time 9000000

Clarification of Answer by studboy-ga on 08 May 2005 09:27 PDT
Also I looked over your pdf file (description): for them they do the
count from 8 down to 0 instead of our 0 to 8 above -- it doesn't
really matter.  If you want 8 down to 0, initialize it to 8, count =
count - 1'b1, and assign busy = (count != 0);

Request for Answer Clarification by motts786-ga on 08 May 2005 14:46 PDT
How would I input a negative number to test it?

Request for Answer Clarification by motts786-ga on 08 May 2005 14:47 PDT
It runs infinitely when i enter a negative #

Clarification of Answer by studboy-ga on 08 May 2005 15:09 PDT
Your instructor's testbench already tests negative numbers--no need to
change anything (the range of numbers is -127 to 127):

		#(2*Del) for (K=127; K>=-127; K=K-1) begin
			for (J=127;J>=-127; J=J-1) begin

Request for Answer Clarification by motts786-ga on 08 May 2005 15:11 PDT
One more question, Could you post a different version of the
multiplier, still using booths algorithm. I can post a new question
with a new price if you would like. Thank You

Clarification of Answer by studboy-ga on 08 May 2005 15:11 PDT
Also, depending on the simulator, you might want to try negedge in your testbench
(for my simulator, the negedge didn't work):

play with:
@(posedge Clk) Start = 1;
or:
@(negedge Clk) Start = 1;

Clarification of Answer by studboy-ga on 08 May 2005 15:13 PDT
I think it's not necessary to have a different version--the version we
have is "industry standard"--you can run it in synthesis through
Synopsys and it's used by every company in Silicon Valley.

Since we are ahead of schedule, why don't you email this version we
have to your instructor/TA?  If he says OK, it would save us both
time/money :)

Clarification of Answer by studboy-ga on 08 May 2005 15:14 PDT
If he says not OK, then you can post the question on Monday and I'll
be happy to convert it for you.

Request for Answer Clarification by motts786-ga on 08 May 2005 16:07 PDT
Sounds good, Also I have posted a another document on the link i
previously posted there is a pdf for a shift register implementation.
If you can have a look at that i would appreciate it. If you say you
would be able to do that one then i will post a question for that
specifically and maybe you can lock it so noone else can answer it. I
was going to post that one for $20. Let me know if you are willing to
do that one as well. The link title is "Shifter Lab". Thank You

Request for Answer Clarification by motts786-ga on 08 May 2005 17:26 PDT
I cant seem to get an output using his testbench, with your test bench
where u provide the inputs ie: a=3 b=7 , that test bench outputs
results. But when i run it using the other testbench I do not obtain
any results. You were able to get the following results correct:

simulation result (last line) shows zero errors:

Time =              8999830, Cycles =           6, MC = bb, MP = 6d, Prod = e29f
, Correct prod = e29f, Error = 0, T_Errors =           0
L104 "multiplier.v": $finish at simulation time 9000000


I do not get anything returned as a result

Clarification of Answer by studboy-ga on 08 May 2005 18:46 PDT
Yes, as I mentioned, the testbench from your instructor is a bit
strange.  Initially I can't get anything to print out either.  Can you
either check with your TA and/or give me a username/passwd into your
system?  The testbecn from your instructor can work or crash depending
on the simulator use.

Question: did you use posedge or negedge at this line:

@(posedge Clk) Start = 1;
#Del Start = 1'b0;

Clarification of Answer by studboy-ga on 08 May 2005 18:49 PDT
Also, make sure it compiles ok.  For my one of my simulators, the
$display line needs to be changed from:

    $display ("Time = %5d, Cycles = %2d, MC = %h, MP = %h, Prod = %h,
Correct prod = %h, Error = %h, T_Errors = %0d",
					$time, Cycles, MC, MP, Prod, Correct, Error, Tot_errors);

to:
    $display ("Time = %d, Cycles = %d, MC = %h, MP = %h, Prod = %h,
Correct prod = %h, Error = %h, T_Errors = %d",
					$time, Cycles, MC, MP, Prod, Correct, Error, Tot_errors);

Request for Answer Clarification by motts786-ga on 08 May 2005 18:51 PDT
I used negedge, then I also tried with posedge

Request for Answer Clarification by motts786-ga on 08 May 2005 18:52 PDT
I put put the entire statement on one line.

Request for Answer Clarification by motts786-ga on 08 May 2005 18:54 PDT
This is the result I obtain (Using Silos):

 S I L O S  Version 2001.120    

      DEMO COPY LIMITED TO 200 DEVICES AND 350 LINES OF HDL CODE

       Copyright (c) 2001 by SIMUCAD Inc.   All rights reserved.
       No part of this program may be reproduced,   transmitted,
       transcribed,   or stored in a retrieval system,    in any
       form or by any means without the prior written consent of

         SIMUCAD Inc., 32970 Alvarado-Niles Road, Union City,   
                     California, 94587, U.S.A.                  
                (510)-487-9700  Fax: (510)-487-9721             
          Electronic Mail Address:   "silos@simucad.com"   

!file .sav="lab3"

!control .sav=3

!control .enablecache

!control .savcell=0

!control .disk=1000M

Reading "multiplier.v"
Reading "test_booth_8.v"
sim to 0
	Highest level modules (that have been auto-instantiated):
		test_Booth_8
	5 total devices.
	Linking ...

	76 nets total: 84 saved and 0 monitored.
	132 registers total: 132 saved.
	Done.                 

	0 State changes on observable nets.

	Simulation stopped at the end of time 0.
Ready: sim 

	3600055 State changes on observable nets in 2.69 seconds.
	1338310 Events/second.

	Simulation stopped at the end of time 9000000.
Ready:

Clarification of Answer by studboy-ga on 08 May 2005 19:26 PDT
OK, from the output you posted I observed a couple of things:

1) It compiled fine
2) It seems to run till 9000000 ns , which is fine
3) Somehow the display statement is not printing out anything at all--

Here, do an experiment--

replace the $display statement with just a simple:

$display("test");

Try it for both posedge and negedge.
And let me know what happens.

Also, post your testbench -- just in case I caught anything that can
go wrong when you copy and paste from the web browser--sometimes that
happens.

Clarification of Answer by studboy-ga on 08 May 2005 19:27 PDT
Also, let me know whether you see anything on the waveform.

Clarification of Answer by studboy-ga on 08 May 2005 19:29 PDT
BTW, regarding the shifter--the pdf says the due date is 3/29.  I
assume its overdue and you need it in a hurry.  I don't think I have a
chance to look at it until tomorrow--you can post it and say, for
studboy only and I will look at it tomorrow.

Request for Answer Clarification by motts786-ga on 08 May 2005 19:50 PDT
Yeah its over due, but I need it by the 10th for sure. So if you can I
will definitely post it tonight and say for studboy only. I am going
to go back to the lab and try what you posted about the multiplier I
will let you know when I get there thanks.

Clarification of Answer by studboy-ga on 08 May 2005 20:13 PDT
OK, let me know. I need to go out for some dinner for a couple of
hours. Will respond when I get back.

Request for Answer Clarification by motts786-ga on 08 May 2005 20:29 PDT
Seems the same
output from replacing with $display ("test"); :
 Copyright (c) 2001 by SIMUCAD Inc.   All rights reserved.
       No part of this program may be reproduced,   transmitted,
       transcribed,   or stored in a retrieval system,    in any
       form or by any means without the prior written consent of

         SIMUCAD Inc., 32970 Alvarado-Niles Road, Union City,   
                     California, 94587, U.S.A.                  
                (510)-487-9700  Fax: (510)-487-9721             
          Electronic Mail Address:   "silos@simucad.com"   

!file .sav="lab3"

!control .sav=3

!control .enablecache

!control .savcell=0

!control .disk=1000M

Reading "multiplier.v"
Reading "test_booth_8.v"
sim to 0
	Highest level modules (that have been auto-instantiated):
		test_Booth_8
	5 total devices.
	Linking ...

	76 nets total: 84 saved and 0 monitored.
	132 registers total: 132 saved.
	Done.                 

	0 State changes on observable nets.

	Simulation stopped at the end of time 0.
Ready: sim 

	3600055 State changes on observable nets in 2.74 seconds.
	1313888 Events/second.

	Simulation stopped at the end of time 9000000.
Ready: 

Question: What simulator are you using?
ALSO here is the testbench I run the simulation with.

/* test_Booth_8 is a test fixture to test an 8-bit Booth multiplier. */
module test_Booth_8;
reg [7:0] MC, MP;
reg [15:0] Correct;
reg Clk, Start;
reg Error;
integer Tot_errors, Cycles;
integer J,K;
wire [15:0] Prod;
wire Busy;
parameter Del = 5;
// Stopwatch
initial begin
#9000000 $finish;
end
// Clock generator
initial begin Clk = 0; forever #Del Clk = ~Clk; end
/* Initialize certain startup variables.
Loop and generate potentially exhaustive sequence
of multiplier and multiplicand values.
Gather data about any incorrect products that might be calculated. */
initial begin
Start = 0;
Tot_errors = 0;
Cycles = -2;
#(2*Del) for (K=10; K>=-10; K=K-1) begin
for (J=10;J>=-10; J=J-1) begin
MC = K;
MP = J;
Correct = K*J;
Error = 0;
@(posedge Clk) Start = 1;
#Del Start = 1'b0;
@(posedge Busy) if (Correct!==Prod) Error = 1;
Tot_errors = Tot_errors + Error;
check (Correct); // Use this line for detailed output.
end
end
check (Correct); // Use this line and uncheck "Save all sim data" for
shorter run time.
end
/* Calculate number of cycles to perform each multiplication. The value -2
compensates for extra cycles that are included in the count. */
always @ (posedge Clk or Busy) begin
if(Busy) Cycles = Cycles + 1;
else #1 Cycles = -2;
end
// Print information about each product calculated.
task check;
input [15:0] Correct;

$display ("test");
 //("Time = %5d, Cycles = %2d, MC = %h, MP = %h, Prod = %h, Correct
prod = %h, //Error = %h, T_Errors = %0d", $time, Cycles, MC, MP, Prod,
Correct, Error, //Tot_errors);
endtask
// Module instances
multiplier B8 (Prod, Busy, MC, MP, Clk, Start);
endmodule

Request for Answer Clarification by motts786-ga on 08 May 2005 20:32 PDT
BTW
I ran it with both posedge and negedge. So disregard that change shown
in the testbench.

Clarification of Answer by studboy-ga on 08 May 2005 22:36 PDT
I'm using Cadence NC-Verilog.  I took the exact file you posted, ran
it here and it prints out test as expected, which I didn't see your
output.

So I'm baffled.  Can you try one more thing?
Clean out everything in your directory, then do a brand-new recompile and see.
If it doesn't work, I'd check with the TA tomorrow--seems like
something with the simulator.

Clarification of Answer by studboy-ga on 08 May 2005 22:39 PDT
Another thing we can try--
change the 9000000 in the testbench to something like 900--
I wonder if it's a memory issue/bug in the simulator.

Request for Answer Clarification by motts786-ga on 08 May 2005 23:18 PDT
This is the response I got when i asked someone else about this tester issue:

"I think the solution was that I got everything synched 
up with the tester's clock cycle, and then it displays fine. 
I'm betting that the problem is that your program just isn't timed
right with the tester. "

Clarification of Answer by studboy-ga on 08 May 2005 23:59 PDT
Can you ask him what does he meant by the tester?  Is it possible that
he can show you his testbench?  Can you try one more thing?
Change the parameter Del value :  currently it's 5, try changing it to 1, then 10.

Clarification of Answer by studboy-ga on 09 May 2005 00:14 PDT
Also, please don't change the testbench where it's not necessary--

for example, I caught you changing this line:

@(posedge Busy) if (Correct!==Prod) Error = 1;

This is incorrect--
Please put back the original:

@(negedge Busy) if (Correct-Prod) Error = 1;

Clarification of Answer by studboy-ga on 09 May 2005 00:16 PDT
The reason it's incorrect is because when the thing is "busy" you
cannot check the result--you check only at the falling edge of busy
(ie, when it turns not busy).

Request for Answer Clarification by motts786-ga on 09 May 2005 00:24 PDT
Ok I will change it back to the original. By "tester" he meant the
testbench. And actually the testbench he and I are using are the same.
Sorry Here is an update. The new testbench posted by the instructor
is:

COMMENT:  This text document contains the revised testbench for
testing Booth's algorithm. It should be used when you present results
of the assignment. It differs from the original version in the test
made in the following line:
@(negedge Busy) if (Correct!==Prod) Error = 1;
It also includes a commented line that can be used to display results
when only the final results are to be displayed.

/* test_Booth_8 is a test fixture to test an 8-bit Booth multiplier. */

module test_Booth_8;
	reg [7:0] MC, MP;
	reg [15:0] Correct;
	reg Clk, Start;
	reg Error;
	integer	Tot_errors, Cycles;
	integer J,K;  
	wire [15:0] Prod;
	wire Busy;
	parameter Del = 5;

// Stopwatch
  initial begin
  #9000000 $finish;
  end

// Clock generator
	initial begin Clk = 0; forever #Del Clk = ~Clk; end

/* Initialize certain startup variables. 
Loop and generate potentially exhaustive sequence
of multiplier and multiplicand values.
Gather data about any incorrect products that might be calculated. */

	initial begin
		Start = 0;
		Tot_errors = 0;
		Cycles = -2;
		#(2*Del) for (K=127; K>=-127; K=K-1) begin
			for (J=127;J>=-127; J=J-1) begin
				MC = K;
				MP = J;
				Correct = K*J;
				Error = 0;
				@(negedge Clk) Start = 1;
				#Del Start = 1'b0;
				@(negedge Busy) if (Correct!==Prod) Error = 1;
				Tot_errors = Tot_errors + Error;
				check (Correct);	// Use this line for detailed output.
				end
			end 
//			check (Correct);	// Use this line and uncheck "Save all sim data"
for shorter run time.
		end

/* Calculate number of cycles to perform each multiplication. The value -2 
compensates for extra cycles that are included in the count. */

	always @ (posedge Clk or Busy) begin
		if(Busy) Cycles = Cycles + 1;
		else #1 Cycles = -2;
		end
// Print information about each product calculated.

  task check;
    input [15:0] Correct;
    $display ("Ver2_Time = %5d, Cycles = %2d, MC = %h, MP = %h, Prod =
%h, Correct prod = %h, Error = %h, T_Errors = %0d",
					$time, Cycles, MC, MP, Prod, Correct, Error, Tot_errors);
  endtask

// Module instances
Booth_Multiplier_8 B8 (Prod, Busy, MC, MP, Clk, Start);

endmodule

Clarification of Answer by studboy-ga on 09 May 2005 00:46 PDT
OK, try one more thing (be sure to use the testbench from your instructor as is):

Change the posedge in the multiplier from posedge to negedge.

I bet that would fix the problem.  Give that a try.

module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q, M;
reg Q_1;
reg [3:0] count;

wire [7:0] sum, difference;

always @(negedge clk)
begin
   if (start) begin
      A <= 8'b0;      
      M <= mc;
      Q <= mp;
      Q_1 <= 1'b0;      
      count <= 8;
   end
   else begin
      case ({Q[0], Q_1})
         2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
         2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
         default: {A, Q, Q_1} <= {A[7], A, Q};
      endcase
      count <= count - 1'b1;
   end
end

alu adder (sum, A, M, 1'b0);
alu subtracter (difference, A, ~M, 1'b1);

assign prod = {A, Q};
assign busy = (count != 0);

endmodule

Request for Answer Clarification by motts786-ga on 09 May 2005 10:11 PDT
I actually tried that last night and still nothing. Also I noted that
for the (A-M) operation you add "a+b+cin" I understand that this is
supposed to be
A+(-M) but I'm pretty sure that with some combinations of numbers this
will give an incorrect result. Reason is that its different to add the
~M with A and then add one to this result. If I'm not mistaken, with
some combinations of numbers this will produce an incorrect result.

Also can you explain to me where you are performing the ASR(arithmatic shift right).

Clarification of Answer by studboy-ga on 09 May 2005 11:41 PDT
1) -M = ~M + 1, this is a property that works fine for the range of
numbers in the specification.  If you don't like that way of doing
way, create a
subtractor module, and just do:

assign out = a - b.

No big deal, right?

2) The ASR is done in the case statement:

         2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
         2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
         default: {A, Q, Q_1} <= {A[7], A, Q};

Make sure you understand EVERY single statement in the multiplier,
adder, AND testbench--they will show up on the exam.

3) If the negedge don;t work I ran out of ideas.  You have 3 choices:

   a) Check with the TA--they are getting paid to be TA, so it's their
      job to help you.
   b) Work with a friend--plug my multiplier into your friend's env/testbench
       and see what happens.  You are not giving him the answer, you are
        working to resolve a common problem.
   c) Submit my first testbench instead of the don't testbench.

Request for Answer Clarification by motts786-ga on 09 May 2005 11:53 PDT
Thank you, i have posted the question for the shifter I need in a
seperate question as u said, i noted (for studboy-ga). The link for
the description is on the same page as the others. Thank You

Clarification of Answer by studboy-ga on 09 May 2005 11:59 PDT
OK, I will take a look at the shifter.  For the testbench, try playing with the 

Parameter Del = 5;

Try setting to 0, along with the negedge in the multiplier, and see what happens.

Request for Answer Clarification by motts786-ga on 09 May 2005 13:01 PDT
Like you stated before, it compiles fine. I actually plotted the
results on a timing diagram in a one-step at a time manner. To my
surprise, "busy" is never shown as being high or low as is the case
with "A". I will post the diagram on the website in a little bit so
you can see this.

Request for Answer Clarification by motts786-ga on 09 May 2005 13:30 PDT
BTW does the asr that you are doing Move shift bits from A into Q into Q_1 ?
Does it treat it as if it is one register and shift all the bits IE: Before
    A           Q         Q_1
1000 0000   0001 0001      0

After ASR:
    A           Q         Q_1
1100 0000   0000 1000      1

Clarification of Answer by studboy-ga on 09 May 2005 13:37 PDT
For the waveform, can you view/post the count in addition to busy?  Do
you see X instead of high/low?  Thanks.

The answer to your second question about ASR is yes--
everythign is concatenated.  YOu should be able to view it as you said
on the waveform.

Request for Answer Clarification by motts786-ga on 09 May 2005 17:28 PDT
Yeah the wave form show all X's for all the values except start, clk, mc, and mp.

Clarification of Answer by studboy-ga on 09 May 2005 19:46 PDT
Can you snap a waveform in gif or pdf format and post it on your  website?

I want to see :

1) count[3:0]
2) start
3) clk
4) busy


Also, can you repost YOUR version of multiplier.v in its entirety?  I
wonder if there's a cut and paste error.

Clarification of Answer by studboy-ga on 09 May 2005 19:47 PDT
Please reply quickly as we have one day left.  Thanks.

Request for Answer Clarification by motts786-ga on 09 May 2005 21:46 PDT
I will post a snap shot in the next 10 mins of these values

Request for Answer Clarification by motts786-ga on 09 May 2005 22:18 PDT
Timing diagram is there, this is the version of the multiplier i'm running with:

module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q, M;
reg Q_1;
reg [3:0] count;

wire [7:0] sum, difference;

always @(posedge clk)
begin
   if (start) begin
      A <= 8'b0;      
      M <= mc;
      Q <= mp;
      Q_1 <= 1'b0;      
      count <= 4'b0;
   end
   else begin
      case ({Q[0], Q_1})
         2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
         2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
         default: {A, Q, Q_1} <= {A[7], A, Q};
      endcase
      count <= count + 1'b1;
   end
end

alu adder (sum, A, M, 1'b0);
alu subtracter (difference, A, ~M, 1'b1);

assign prod = {A, Q};
assign busy = (count < 8);

endmodule

//The following is an alu.  
//It is an adder, but capable of subtraction:
//Recall that subtraction means adding the two's complement--
//a - b = a + (-b) = a + (inverted b + 1)
//The 1 will be coming in as cin (carry-in)
module alu(out, a, b, cin);
output [7:0] out;
input [7:0] a;
input [7:0] b;
input cin;

assign out = a + b + cin;

endmodule

Clarification of Answer by studboy-ga on 09 May 2005 22:26 PDT
OK, I see the waveform. I hope you see the problem as well as I do :
the Start pulse is TOO SMALL.  According to the spec, the Start pulse
is supposed to be 5 clock cycles.  Depending on the simulator, in this
case yours, the Start signal won't even get latched.

Modify the testbench as follows:

Change:

@(negedge Clk) Start = 1;
#Del Start = 1'b0;

To something like:

@(negedge Clk) Start = 1;
#(2*Del) Start = 1'b0;

Or:

@(negedge Clk) Start = 1;
#(Del+1) Start = 1'b0;

Clarification of Answer by studboy-ga on 09 May 2005 22:29 PDT
The multiplier.v you posted looks fine.  If you're using the latest
testbench, be sure to use negedge:

module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q, M;
reg Q_1;
reg [3:0] count;

wire [7:0] sum, difference;

always @(negedge clk)
begin
   if (start) begin
      A <= 8'b0;      
      M <= mc;
      Q <= mp;
      Q_1 <= 1'b0;      
      count <= 8;
   end
   else begin
      case ({Q[0], Q_1})
         2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
         2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
         default: {A, Q, Q_1} <= {A[7], A, Q};
      endcase
      count <= count - 1'b1;
   end
end

alu adder (sum, A, M, 1'b0);
alu subtracter (difference, A, ~M, 1'b1);

assign prod = {A, Q};
assign busy = (count != 0);

endmodule

Clarification of Answer by studboy-ga on 09 May 2005 22:34 PDT
Make the Start pulse bigger--like 5*Del, should solve the problem.

@(negedge Clk) Start = 1;
#(5*Del) Start = 1'b0;

If the pulse is biffer, it actually doesn't matter whether it's
posedge or negedge inside multiplier.v.

Clarification of Answer by studboy-ga on 09 May 2005 22:37 PDT
Also, regarding the shifter, if you can get the deadline extended till
next Monday (or even till the end of the week) I maybe able to help
you.  As you can see, most of the time we spent is in debugging.  The
coding takes very little time, but debugging can take forever. 
Thanks.

Request for Answer Clarification by motts786-ga on 09 May 2005 22:41 PDT
Ok i'm trying what you just suggested, and about the shifter, The
absolute latest is 5/11/05 by 3:00 p.m.

Clarification of Answer by studboy-ga on 09 May 2005 22:42 PDT
There's another trick to get around the small Start pulse--

in multiplier.v, change:

always @(posedge clk)

to:

always @(posedge clk or start)

Give that a try!

Request for Answer Clarification by motts786-ga on 09 May 2005 23:23 PDT
That did the trick!!! Thank You very much.

Clarification of Answer by studboy-ga on 10 May 2005 00:05 PDT
Great!
motts786-ga rated this answer:5 out of 5 stars
Studboy was Extremely helpful, and definitely has a very well
understanding in the subject material related to the question posted.
Very efficient and prompt in his answer. Thank you studboy

Comments  
There are no comments at this time.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy