Forum Discussion

FOudm's avatar
FOudm
Icon for New Contributor rankNew Contributor
8 years ago

ModelSim error: unexpected internal error in Questa

Dear all,

I'm trying to simulate the following piece of code:

module peak_detect #(
	parameter BATCH_SIZE,
	parameter DATA_WIDTH
)(
	input		wire							clk,
	input		wire							reset,
	input		wire							sink_sop,
	input		wire							sink_eop,
	input		wire							sink_valid,
	input		wire	[DATA_WIDTH-1:0]	sink_re,
	input		wire	[DATA_WIDTH-1:0]	sink_im,
	output	bit							source_sop,
	output	bit							source_eop,
	output	bit							source_valid,
	output	int							source_freq,
	output	int							source_mag,	
	output	int							source_phaseA,
	output	int							source_phaseB
);
 
// more parameters
localparam BIN_WIDTH = 10;
localparam NPEAKS = 4;
localparam shortint EXPEAKS[NPEAKS] = '{200, 400, 600, 800};
localparam PEAKDEV = 50;
 
typedef struct {
	shortint	bin;
	byte		delta;
	int		re[0:2];
	int		im[0:2];
	int		mag[0:2];
} chunk;
 
task automatic chunk_reset(ref chunk chnk);
	chnk.bin			<= 0;
	chnk.delta		<= 0;
	for (byte i = 0; i < 3; i++)
	begin
		chnk.re[i]		<= 0;
		chnk.im[i]		<= 0;
		chnk.mag[i]		<= 0;
	end
endtask
 
task automatic chunk_shift(ref chunk chnk);
	chnk.bin			<= chnk.bin + 1;
	for (byte i = 0; i < 2; i++)
	begin
		chnk.re[i]		<= chnk.re[i+1];
		chnk.im[i]		<= chnk.im[i+1];
		chnk.mag[i]		<= chnk.mag[i+1];
	end
	chnk.re[2]		<= sink_re;
	chnk.im[2]		<= sink_im;
	chnk.mag[2]		<= hypot(sink_re, sink_im) <<< 8;
endtask
 
chunk										buffer;
chunk										peaks[0:NPEAKS-1];
bit	[$clog2(BATCH_SIZE)-1:0]	sink_pos;
bit										sink_done;
bit	[$clog2(NPEAKS)-1:0]			source_pos;
bit										source_done;
 
always @(posedge clk)
begin
	if (reset || sink_eop)
	begin
		chunk_reset(buffer);
		for (byte i = 0; i < NPEAKS; i++)
			chunk_reset(peaks[i]);
		sink_pos			<= 0;
		sink_done		<= 0;
		source_pos		<= 0;
		source_done		<= 0;
		source_valid	<= 0;
	end
	else if (!sink_done && sink_valid)
	begin
		for (byte i = 0; i < NPEAKS; i++)
			if (EXPEAKS[i]-PEAKDEV <= sink_pos && sink_pos < EXPEAKS[i]+PEAKDEV && buffer.mag[1] > peaks[i].mag[1])
				peaks[i] 		<= buffer;
		chunk_shift(buffer);
		sink_done		<= (sink_pos == BATCH_SIZE - 1) ? 1 : 0;
		sink_pos			<= sink_pos + 1;
	end
	else	
	begin
		source_valid	<= 0;
	end
end
 
endmodule

The code is perfectly synthesisable in Quartus Prime Lite, but ModelSim returns an error when compiling: "Error: C:/[path]/peak_detect.sv(35): Questa has encountered an unexpected internal error: ../../src/vlog/vgencode.c(118)"

If I comment out the calling of the task, ModelSim still gives the same error. So it's something with the task, but I don't know what exactly. Does anyone have an idea how to solve this problem? Am I doing really bad things with my code, or is it a bug in ModelSim?

4 Replies

  • Abe's avatar
    Abe
    Icon for Frequent Contributor rankFrequent Contributor

    Looks like the both the automatic tasks are causing this error. Have you tried commenting out both the automatic functions and checking if it compiles without errors. You may want to use normal tasks and remove the ref keyword and compile.

    Convert the tasks to normal without the reference.

  • Agreed to Abe. To debug further, try not to use passing reference in the argument in the task.

  • FOudm's avatar
    FOudm
    Icon for New Contributor rankNew Contributor

    Thanks for both answers.

    It had indeed something to do with the reference passing in combination with the non-blocking assignments. It's weird that the Quartus synthesizer no problems found, but Modelsim did.

    I've solved the problem by completely eliminating both tasks by integrating them into the always-block.