[SOLVED] Verilog Error : Too Few Parameters Passed To Task

Status
Not open for further replies.

AshkanYJM

Junior Member level 3
Joined
Aug 3, 2014
Messages
25
Helped
1
Reputation
2
Reaction score
1
Trophy points
3
Visit site
Activity points
262
Hi,
The verilog code below is a part of my project but i come upon errors when I run the program.

Code:
module multieffect(Buff_Array,Audio_out,Clk);
input [11:0]Buff_Array;
input Clk;
output [11:0]Audio_out;
integer k;

   task divide; 
      input [11:0] Buff_Array; 
      output [11:0] Buff_Array1;		
      assign Buff_Array1=Buff_Array>>1;
   endtask
		
task echo;
input  [11:0] Buff_Array,Buff_Array1;
input Clk;
output [11:0] Audio_out;
integer t;
forever @(posedge Clk)
begin
assign Audio_out=Buff_Array[0]+ divide(Buff_Array[t],Buff_Array1[t]);
end
endtask
.
.
.
echo(Buff_Array,Audio_out);
.
.
.
.
endmodule

and here is the error I get :

ERROR:HDLCompilers:160 - "Multieffect.v" line 1713 Too few parameters passed to task 'echo'

I can't figure it out, What's the problem ?
 

It's a pretty self explanatory error message.

Regards
 

Thanks for your answer, But Frankly I thought the task(A,B) where A is input and B is Output suffices and everything in between is unnecessary to mention. Yet I added Clk and Buff_Array1 but Errors I got became more complicated!

echo(Buff_Array,Audio_out,Clk,Buff_Array1);

resulted into this:

ERROR:HDLCompilers:28 - "Multieffect.v" line 1713 'Buff_Array1' has not been declared

and defining Buff_Array1 in module doubled the errors, so I suppose either that is not the way or something else is the problem.
 

I'm not that clumsy with verilog believe me, I've read the link you shared and other links also but according to them nothing is wrong with my tasks(as far as i can see!) but yet they give errors.
Let me post my whole code.It is intended for implementing a guitar multieffect processor.

Code:
[I]
module CircularBuffer(Audio_in, Clk, Reset,control,t);
input signed [11:0] Audio_in;
input Clk,Reset,control,t;
reg [11:0]Buff_Array[4095:0];
integer k;
always @ (posedge Clk)
  begin
     if (Reset == 1)
        for (k = 0; k <= 4095; k = k+1)
             Buff_Array[k] <= 0;
     else
        begin
           Buff_Array[0] <= Audio_in;
          for (k = 1; k <= 4095; k = k+1)
           Buff_Array[k] <= Buff_Array[k-1];
       end
end

endmodule 


module multieffect(Buff_Array,Audio_out,Clk);
input [11:0]Buff_Array;
input Clk;
output [11:0]Audio_out;
integer k;

   task divide; 
      input [11:0] Buff_Array; 
      output [11:0] Buff_Array1;		
      assign Buff_Array1=Buff_Array>>1;
   endtask
		
task echo;
input  [11:0] Buff_Array,Buff_Array1;
input Clk;
output [11:0] Audio_out;
integer t;
forever @(posedge Clk)
begin
assign Audio_out=Buff_Array[0]+ divide(Buff_Array[t],Buff_Array1[t]);
end
endtask

task chorus;
input [11:0] Buff_Array,Buff_Array1;
output [11:0] Audio_out;
integer G;
forever@(posedge Clk)
begin 
for (k=1;k<=801;k=k+1)
case (k)	
...
endcase

assign Audio_out=Buff_Array[0]+ divide(Buff_Array[G],Buff_Array1[G]);
end
endtask

task Flanger;
input [11:0] Buff_Array,Buff_Array1;
output [11:0] Audio_out;
integer G;
forever@(posedge Clk)
begin 
for (k=1;k<=400;k=k+1)
case (k)
...
endcase


assign Audio_out=Buff_Array[0]+divide(Buff_Array[G],Buff_Array1[G]);
end
endtask


task Phaser;
input [11:0] Buff_Array,Buff_Array1;
output [11:0] Audio_out;
integer G;
forever@(posedge Clk)
begin 
for (k=1;k<401;k=k+1)
case (k)
...
endcase

assign Audio_out=Buff_Array[0]- divide(Buff_Array[G],Buff_Array1[G]);
end
endtask
reg [1:0] control;
always @ (posedge Clk)
begin
 case (control)
   2'b00 : echo(Buff_Array,Audio_out,Clk,Buff_Array1);
   2'b01 : chorus (Buff_Array,Audio_out,Clk,Buff_Array1);
   2'b10 : Phaser (Buff_Array,Audio_out,Clk,Buff_Array1);
	2'b11 : Flanger(Buff_Array,Audio_out,Clk,Buff_Array1);
endcase
end
endmodule[/I]

So what do you see fellas? it has reached to a very irritating point so your help would mean very much to me.
 

Alright, benefit of the doubt then... Could you post the entire code. Without ... snippets, and please using

Code Verilog - [expand]
1
2
3
tags so we get line numbers. And if you then copy/paste the actual error messages you get (with the line numbers and all that) that makes remote debugging somewhat less painful. ;)
 
On second thought, since the error mentions line numbers in the 1k region, better to attach the relevant files + past the error message.

 


Code:
task echo;
input  [11:0] Buff_Array,Buff_Array1;
input Clk;
output [11:0] Audio_out;
integer t;
[COLOR="#FF0000"]forever @(posedge Clk)[/COLOR]
begin
assign Audio_out=Buff_Array[0]+ divide(Buff_Array[t],Buff_Array1[t]);
end
endtask

If the above read text means you are going to synthesize this code and build some hardware to do this...
You can't synthesize tasks with time control statements.

Let me guess you're used to software programming and Verilog looks like software?

You'll have to design the circuits to perform your echo capability. My suggestion get rid of all the tasks they really have no place in synthesizable designs (regardless of what others might think) a function is synthesizable. The only reason I can envision using a task is because you can have more than one output from the task, but I'm not into burying potentially huge amounts of combinational logic inside a task/function that gets assigned to some register in a always. That's a great way to end up with slow designs, that don't meet timing.

Regards
 
Didn't even read that it was meant to be synthesizable. I was taking him on his word that he wasn't that clumsy with verilog, so no need for me to verify his code until the point in time we have all the code + error line numbers. It's called lazy evaluation.
 

Oh yes not at all clumsy with Verilog....

Code:
reg [11:0]Buff_Array[4095:0];
integer k;
always @ (posedge Clk)
  begin
     if (Reset == 1)
        for (k = 0; k <= 4095; k = k+1)
             Buff_Array[k] <= 0;
     else
        begin
           Buff_Array[0] <= Audio_in;
          for (k = 1; k <= 4095; k = k+1)
           Buff_Array[k] <= Buff_Array[k-1];
       end
end
49,152 registers needed right here, hope you are using a big part.
 

 

Attachments

  • Multieffect.rar
    4.3 KB · Views: 88

I believe that in internet parlance this is known as a LOLWUT?


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
reg [1:0] control;
always @ (posedge Clk)
begin
  case (control)
    2'b00 : echo(Buff_Array,Audio_out,Clk,Buff_Array1);
    2'b01 : chorus (Buff_Array,Audio_out,Clk,Buff_Array1);
    2'b10 : Phaser (Buff_Array,Audio_out,Clk,Buff_Array1);
    2'b11 : Flanger(Buff_Array,Audio_out,Clk,Buff_Array1);
endcase
end



I get the underlying idea, but that is not how you describe the hardware using this here verilog HDL.

What you probably want to do is make seperate MODULES (otherwise known as "throw out those tasks") for each of your effects. And then where you you have that case statement you use a MUX to select the correct module output.

- - - Updated - - -

Also, if you ever intend to use this on a an actual fpga board and use a filter that uses up a large-ish amount of memory you basically have 2 options:
- use block ram resources (BRAM)
- use external DRAM

If you use BRAM then check your fpga docs to check how much you have available to you, and then design accordingly. If you use external DRAM you will probably have plenty of memory to do your thing, buuuut then you will have to mess with the MIG which is not without learning curve.

Short version of that advice is: use BRAM since that is relatively easy. Best use core generator to generate the block ram for you, and use the instantiation template for that module.

Or you can of course use your current method & hope for the best. Your project, your time.
 
Unless you've got a lot of experience designing logic in FPGAs, avoid using functions or tasks, I would completely avoid them. It hides to much combinational logic and can lull one into a false sense of thinking their design can make 400 MHz timing, when it can barely make 100 MHz. I've been doing this for 15+ years and I seldom use functions and never use tasks in synthesizable code.

This says I think like a software programmer and not a hardware engineer more than anything you've said so far. Your trying to force fit Verilog into a software model, that you are used to. Verilog is all about writing hardware descriptions instead of drawing schematics and is not like writing "programs".

To do this like a hardware design: Design the circuit using detailed block diagrams, and schematic type stuff (registers, muxes, memories, fifos, FSMs, etc) first. Don't write any code until you have a design that should conceivably do what you want. Now describe that design in Verilog, and run RTL simulations to verify functionality.

This is no different than "real" software development, where you write a SW spec, draw up flow diagrams, etc (doing the design) then you write the program and run unit tests.

You don't want to use memory (registers) you want to use memory as in RAM. Only if you need parallel access to all locations of "memory" simultaneous do you need to use registers. By using registers you're increasing the cost of the FPGA used significantly. Big FPGA == Big cost (fast&big FPGA == Very big cost)

You're using integer, integer in Verilog is defined as 32-bit, now you are relying on the synthesis tool to trim the extra bits (not a good way to design something).
The for loop around the case statements won't do what you want i.e. produce a ROM. The for loop in Verilog is not a construct to loop through iterations of executing code it unravels into parallel hardware.
You really don't have a clue how to write a Verilog hardware descriptions regardless of your claim...I'm not that clumsy with verilog believe me
You need to read a good Verilog book on writing synthesizable code, of which there are many on Amazon. And you need to throw away all your software programming knowledge and think in terms of hardware circuits.

When I see the following code:
Code:
always @ (posedge clk) q[7:0] <= d[7:0];
I see something equivalent to a 374 8-bit register, I don't see Verilog code anymore.

Regards

- - - Updated - - -

Something else that bothers me.
`timescale 1ns / 1ps

Should not be in synthesizable code.

Besides I've read a number of papers on test results of messing around with timescale and it seems to be better to use the same value for both the time unit and precision. So running with 1ns/1ns is pretty close on par with 1ps/1ps, but using 1ns/1ps will slow a simulation down.
 



Thanks for your answers. Whereas This Project is due very soon, I can not apply some kind of hardware design perfectionism in it. I know what ads-ee said makes the best of a project, But with the time I have left I think the best I can do is to convert my tasks into modules and use a MUX instead of a case statement, Like what mrflibble said. That was also one of my questions but I could not find an answer! difference between a task and a module and why someone should use a task instead of an ordinary module.
But here again there is a difference between a MUX and a case. MUX chooses an output from a group of outputs, it means that my hardware has to make all the effects outputs ready to go at the gates of the MUX, but my case statement Chooses what my hardware should do! I think in this case, my way saves a lot of time. consider that my input/output is sound so it's a real-time process. So the sum of the delays of every block and process ought to be less than a ms.

I have to ask for your suggestion again, with what I said what is the best solution ?
 

Thanks for your answers. Whereas This Project is due very soon, I can not apply some kind of hardware design perfectionism in it. I know what ads-ee said makes the best of a project
Never suggested perfection, just good design process.

But with the time I have left I think the best I can do is to convert my tasks into modules
I would have suggested the same if I was going to tell you how to do it. I was going to let you figure out what you should do.

and use a MUX instead of a case statement, Like what mrflibble said. That was also one of my questions but I could not find an answer!
You can code a mux using a case statement, what makes you think otherwise? I've looked on various sites https://lmgtfy.com/?q=coding+a+mux+in+verilog and they all show using case statements and a few other methods.

difference between a task and a module and why someone should use a task instead of an ordinary module.
This statement shows how much you need to read a book on Verilog. Tasks should be used in testbenches, modules are like ICs on a board, so you can partition the design up and not end up with one huge un-maintainable file with 10K lines of code.

Do you mean your task based design is the better way? Well I guess you know best as you've stated previously how good you are at Verilog "programming". Verilog is a hardware description language stop trying to force fit it into a software programming approach. You need to know what hardware you want to create and then write a description that describes that hardware.

I have to ask for your suggestion again, with what I said what is the best solution ?
A hardware design that does NOT use any tasks. But I don't see this happening as it appears you seem to be stuck in your software design paradigm and are unwilling to throw away your badly written Verilog "program" and start over with a properly pipelined hardware implementation.

Regards
 



No not at all. I am not insisting on using tasks, I'm saying a MUX lets out an output from 4,8 or more input that already have a value or a processed signal. But the last case statement I have written in my code DECIDES what the program must do! so there's a difference. I want to decide from outside,what effect ought to be applied to my input and I suspect that using a mux with modules slows down the device. Because modules work in parallel and MUX only chooses an output from 4 already available outputs. Am I right ?
 

You have no specification of what your circuit is trying to accomplish, so how are we supposed to know what you require?

Run the input through all of the modules that perform each effect. You select which effect is output with the mux. The mux doesn't slow anything down it just routes the effect you want applied out of the module.

- - - Updated - - -

You know I have a better suggestion...

Get a 6 core i7 processor (PC) and write software for each effect and run each effect on a single processor, then use another core to decide which of the effects will be output. Then you can have your program decide what to do next, without having to describe any hardware.
 

But the last case statement I have written in my code DECIDES what the program must do! so there's a difference.

Indeed, there is a difference. Your PROGRAM that DECIDES what it must do relies on wishful thinking and/or the dark arts to magically have the right hardware in place when you toggle the control bits. Unfortunately, real synthesizable hardware does not oblige your wishes.

And as you guessed, with a separate module for EACH effect you will indeed get FOUR pieces of instantiated hardware that are running in parallel. And each will have a valid output, from which you select only one (using the mux). And yes this is suboptimal. And yes, this is because the design stays reasonably close to what you have now, but with the distinct advantage of actually working. If you want to keep the mainstay of your code you will not have the luxury to be all pouty that it is inefficient. The entire current design is inefficient, but I wasn't going to be the first one to bring that up.

If you want something that doesn't blow you probably should implement it as a FIR filter. Then when you select another effect you load the corresponding coefficients into the filter and Tadaaaa new sound effect. But that would mean a complete redesign, so that's something for your Lessons Learned [tm].

As for this: "... and I suspect that using a mux with modules slows down the device ...".. Nooope. Now what kind of java programmer thinking is that. This is parallel hardware we're talking about. Yes it will use up about 4x the resources. Yes, it will use up about 4x the power, but no it will NOT be slower. And yeah yeah, if done properly it will of course not use up 4 times the power, but that is only after some people learn about using clock enables. Which is probably not today. Besides, audio effects don't require such a super high clock so power isn't the number one concern I'd think. Getting something that works seems to be the number one concern.

PS: Get rid of all the tasks. Did I mention that already? Well, get rid of them. See it as a pedagogically responsible way of learning how to get your modules done. Because 1) you really don't need them and 2) they are really just a hindrance, because 3) your current mental process used while designing needs some refinement. And that refinement will happen faster if you just stick to the design challenge of no tasks and no functions. You just think you need them. You imperative programmer you.
 

Mrfibble,

I think my suggestion using a 6 core i7 PC is a better solution for a hardware challenged software programmer.

They probably would have completed their task (pun intended) much sooner. ;-)
 

Yeah, but I still pretend to have high hopes for humanity in general. As soon as he remembers that verilog is a Hardware DESCRIPTION Language he should be half way there already. And if he then remembers what his mother told him,"Never make assumptions Timmy!", he is practically there (well, sortof). Because assuming tasks, functions, loops, etc in verilog behave the same as in an imperative programming language is just that, a big fat assumption.

So as already suggested:
Book. Verilog. Read.

- - - Updated - - -

I just realized I should also add this to the design challenge:

<LOOP_NAZI>
No loop for you!
</LOOP_NAZI>

So no, no loops either. Because that's another fun programmer trap.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…