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.

Verilog Multiplier Module ... Inferred Memory Device as a Latch on Synthesis

Status
Not open for further replies.

tyagifaisal

Newbie level 4
Joined
Feb 25, 2013
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,343
Hi,

I have a Verilog multiplier module which is part of a big hierarchy. When I synthesize it, during the "Elaborate Design" phase (using Synopsys DCS), I get the message that the memory device has been inferred as a latch. I don't have any dangling if...else statement, and if the issue is with the way I am taking care of the 'else' condition, can someone tell me the right way to do it?

Thanks,

Faisal

Here's my code and output from synthesis:

Code:
module mult(in1, in2, out, mult_start);

input signed	[16-1:0]	in1, in2;
input 			mult_start;

output 		signed [32-1:0]	out;
reg 		        signed [32-1:0]	out;

always @(in1 or in2 or mult_start)
begin
	if (mult_start == 1'b1)
	begin
		out <= (in1 * in2);
	end
	else
		out <= out;
end
endmodule



Synthesis Output:
Inferred memory devices in process
in routine mult line 9 in file
'/homes/mult.v'.
===========================================================================
| Register Name | Type | Width | Bus | MB | AR | AS | SR | SS | ST |
===========================================================================
| out_reg | Latch | 32 | Y | N | N | N | - | - | - |
===========================================================================
 

It's because you're connecting out <= out in the else case. This is the behaviour of a latch.
 
It's because you're connecting out <= out in the else case. This is the behaviour of a latch.

The above mult module is instantiated in a top module and I want the multiplication operation to take place only when mult_start has been triggered by the top module. That being said, I am assuming I do want the synthesis tool to infer it as a latch then and this is not unwanted synthesis?

Pieces of my top module:

Code:
`include "mult.v"

module top_module ( clock, reset, mult_start, sig_start, inputA, inputB, ... )
// declare input and output ports

// declare internal variables to be used
reg [3-1:0] state;
reg [8-1:0] index;
reg [15:0] A, B;

// module instantiations
mult mult_a(A, B, output[0], mult_start);

always @(posedge clock)
begin
       if (state == 3'b000)
       begin
              state <= 3'b001;
              mult_start <= 0;
       end
       else if (state == 3'b001)
       begin
             A <= inputA;
             B <= inputB;
             state <= 3'b010;
       end
       else if (state == 3'b010)
       begin
             mult_start <= 1;
             state <= 3'b011;
       end
       else if (state == 3'b011)
       begin
             A <= 0;
             B <= 0;
            mult_start <= 0;
            state <= 3'b100;
       end
end
endmodule
 

As the multipier is not sunchronous, I highly recommend you do not infer latches but rather do the usual thing of registering the output on an enable signal.
 
As the multipier is not sunchronous, I highly recommend you do not infer latches but rather do the usual thing of registering the output on an enable signal.

Do you mean something like:

Code:
module mult(in1, in2, out, mult_start);

input signed	[16-1:0]	in1, in2;
input 			mult_start;

output 		signed [32-1:0]	out;
reg 		        signed [32-1:0]	out_temp;

assign out = out_temp;

always @(in1 or in2 or mult_start)
begin
	if (mult_start == 1'b1)
	begin
		out_temp <= (in1 * in2);
	end
	else
		out_temp <= 0; //out_temp;
end
endmodule

Sorry if I don't get what you mean by 'the usual thing.' This is my first attempt at HDL design, I do most of my coding in software...
 

That would prevent a latch from forming, but it does put a mux on the multiplier output which may be unnecessary.

I dont understand quite why you need to "start" and "stop" the multiplier. Your design appears to just multiply two numbers. You could quite easily see these values on a simulation. You know when data is valid as the "mult_start" signal is high. So it really doesnt matter what the values of A, B or output are when mult_start = 0. The output is only valid when mult_start is high.
 

That would prevent a latch from forming, but it does put a mux on the multiplier output which may be unnecessary.

I dont understand quite why you need to "start" and "stop" the multiplier. Your design appears to just multiply two numbers. You could quite easily see these values on a simulation. You know when data is valid as the "mult_start" signal is high. So it really doesnt matter what the values of A, B or output are when mult_start = 0. The output is only valid when mult_start is high.

I guess I should have explained exactly what I wanted out of this design....I need 200+ of those multipliers and the sum of the 200+ outputs from the multiplier. mult_start sets off the trigger that the multiplier module should start. sig_start sets off the trigger that the sig module which contains LUT for exponential function should start.

I need mult_start and stop trigger cos I also need to add all those outputs at the end in the next stage.

So, my top_module is something like this:

Code:
// instantiate 217 mult modules using generate statements

// top module
always @(posedge clk)
begin
	if (state == 4'b0000)
	begin
		state <= 4'b0001; // initialize variables to zero
		k <= 0;
		result_done <= 0;
	end
	else if (state == 4'b0001) // Start Multiplication Operation
	begin
		k           	<= result_done ?      0 	: k + 1;
        	result_done 	<= result_done ?      1 	: (k == 10); // k = 10 is trial and error value at which I get all 217 multiplier answers
        	state 		<= result_done ?      4'b0010 	: 4'b0001;
        	mult_start 	<= result_done ?      1'b1 	: 1'b0; 
	end
	else if (state == 4'b0010) // Stop Multiplication Operation
	begin
		k <= 0;
		result_done <= 0;
		mult_start <= 0;
		prod_sum <= 0;
		state <= 4'b0011;
	end
	else if (state == 4'b0011) // add everything up
	begin
		k           	<= result_done ?      0 	: k + 1;
        	result_done 	<= result_done ?      1 	: (k == 215);
        	state 		<= result_done ?      4'b0100 : 4'b0011; 

		prod_sum <= prod_sum + prod_1[k];
	end
       else if (state == 4'b0100) // start activation function
	begin
		state <= 4'b0101;
                sig_start <= 1'b1;
	end
         else if (state == 4'b0101) // stop activation function
	begin
		state <= 4'b0110;
                sig_start <= 1'b00;
	end
        else
                state <= 4'b0111; // default: do nothing
end

And my sig LUT is something like:

Code:
// In module sig.v: 
always @(sig_start)
begin
	case (in) 
	   	-100: out <= 495050;
       	 	-99: out <= 500000;
        	-98: out <= 505051;
                 ......
                 default: out <= 495050;
        endcase
end
endmodule

Since I wanted the outputs from the mult module only during the required stages, I simply made it asynchronous on mult_start, not realizing the repercussions this might have when I finish functional simulation and start synthesis!

So, is it better to leave it asynch like my previous post (no latch, but multiplexer synthesized)? Or should I make it synchronous like:

Code:
always @(posedge clk) //(in1 or in2 or mult_start)
begin
	if (mult_start == 1'b1)
	begin
		out <= (in1 * in2);
	end
	else
		out <= (in1 * in2); //out; I don't understand what to do with this else condition here?
end
endmodule

Also, since I also need a sig_start trigger, how can I make that synchronous and latch-free?

Thanks a lot,

Faisal.
 

Since you are a beginner, I would suggest doing some reading up on digital logic design. For a mult-adder tree it is very unusual to have a "start" flag. Remember you will need at least 1 pipeline stage for each multiplier (can all be done in parrellel unless it's serial data) plus one for each adder in the tree, or your max clock frequency is going to be horrendously slow. Then alongside this you just have a "valid" signal that tells the system when the data is valid (so the output is dumped into a fifo or a memory or something).

With 217 parrallel multipliers, you're going to need a pipeline of about 108 (ie. latency of 108 clock cycles) before the output is valid to get any decent fmax.
 
Thanks for the suggestions. I guess it is a horribly inefficient way of taking care of things in hardware. I do have some major reading to do before starting to tackle these problems by writing code!!!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top