AshkanYJM
Junior Member level 3
- Joined
- Aug 3, 2014
- Messages
- 25
- Helped
- 1
- Reputation
- 2
- Reaction score
- 1
- Trophy points
- 3
- Activity points
- 262
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
It's a pretty self explanatory error message.Too few parameters passed to task 'echo'Code:task echo; input [11:0] Buff_Array,[COLOR="#FF0000"]Buff_Array1[/COLOR]; [COLOR="#FF0000"]input Clk;[/COLOR] 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[COLOR="#FF0000"],[/COLOR]Audio_out); [COLOR="#FF0000"]// where is your assignment to [B]clk and Buff_Array1[/B]?[/COLOR] . . . . endmodule
I can't figure it out, What's the problem ?
[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]
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.
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.
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
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
Alright, benefit of the doubt then... Could you post the entire code. Without ... snippets, and please using
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 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.[/QUOTE] the parts that are omitted (...) are look-up tables, a hell lot of numbers. the code here is complete and errors change much with very tiny changes So anyway I have attached the .v file to this post. sorry for the .rar the uploader didn't support .v . Thanks. [COLOR="silver"][SIZE=1]- - - Updated - - -[/SIZE][/COLOR] [QUOTE="ads-ee, post: 1372783, member: 528561"]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[/code] 49,152 registers needed right here, hope you are using a big part.[/QUOTE] [QUOTE="ads-ee, post: 1372779, member: 528561"][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[/code] 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[/QUOTE] ads-ee, you are so right about that, synthesizing is not what i am used to much!! i've had some sessions working with arduino but my main field has been more on softwares. but the matter is, whereas I am working with registers (Memory in fact) I ought to use tasks I suppose. I wanted to know how I could make functions in verilog, I read a lot on the web and references the differences between tasks and functions and eventually i chose task cause it understood delays and could handle registers and multiple outputs! and about the big part,Yes the (RAM,Memory,Train of registers) I need here is huge. I don't have an FPGA board myself, somebody is going to buy that with someone else's funds so I do not know what device I finally have to argue with! yes, I know that sounds weird but I am ready to either get a board with memory on it, or else use an external RAM.
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
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".AshkanYJM said:but the matter is, whereas I am working with registers (Memory in fact) I ought to use tasks I suppose. I wanted to know how I could make functions in verilog, I read a lot on the web and references the differences between tasks and functions and eventually i chose task cause it understood delays and could handle registers and multiple outputs!
always @ (posedge clk) q[7:0] <= d[7:0];
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:I see something equivalent to a 374 8-bit register, I don't see Verilog code anymore.Code:always @ (posedge clk) q[7:0] <= d[7:0];
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.
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.
Never suggested perfection, just good design process.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
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.But with the time I have left I think the best I can do is to convert my tasks into modules
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.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!
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.difference between a task and a module and why someone should use a task instead of an ordinary module.
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.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.
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.I have to ask for your suggestion again, with what I said what is the best solution ?
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.
But the last case statement I have written in my code DECIDES what the program must do! so there's a difference.
Book. Verilog. Read.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?