FFT implementation in Verilog : Error using nested for loop - fft

This post is related to the my previous post related to FFT.
FFT implemetation in Verilog: Assigning Wire input to Register type array
I want to assign output of first stage to input of second stage of FFT butterfly modules. I have to re-order the output of first stage according to input of second stage. Here is my code to implement the swapping.
always# (posedge y_ndd[0] or posedge J)
begin
if(J==1'b1)
begin
for (idx=0; idx<N/2; idx=idx+1)
begin
IN[2*idx] <= X[idx*2*X_WDTH+: 2*X_WDTH];
IN[2*idx+1] <= X[(idx+N/2)*2*X_WDTH+: 2*X_WDTH];
end
end
else
begin
level=level+1;
modulecount=0;
for(jj=0;jj<N;jj=jj+(2**(level+1)))
begin
for (jx=jj; jx<jj+(2**level); jx=jx+1)//jj+(2**level)
begin
IN[modulecount] <=OUT[jx];
IN[modulecount+1] <=OUT[jx+(2**level)];
modulecount=modulecount+1;
end
end
end
end
When I synthesize this, It gives 2 errors.
ERROR:Xst:891 - "Network.v" line 161: For Statement is only supported when the new step evaluation is constant increment or decrement of the loop variable.
ERROR:Xst:2634 - "Network.v" line 161: For loop stop condition should depend on loop variable or be static.
Can't we use non-constant increment and non-static stop coditions?
If that so, how we handle this.
Any help is appreciated.
Thanks in advance.

Synthesis tools unroll loops in order to synthesize the circuit. Therefore, only loops that iterate a constant number of times, whose constant is known at compile/elaboration time are synthetisable.
When the stop value is not known, you can assume a maximum number of iterations and use that as the stop condition. Then add the original stop condition as a conditional statement inside the loop:
for (jx=jj; jx < MAX_LOOP_ITERATION; jx=jx+1)//jj+(2**level)
begin
if (jx<jj+(2**level)) // <---------- Add stop condition here
begin
IN[modulecount] <=OUT[jx];
IN[modulecount+1] <=OUT[jx+(2**level)];
modulecount=modulecount+1;
end
end
If N is not a constant, the outer loop should also be fixed using a similar conditional statement. You also need to fix the increment value and each time add a constant value. Use a conditional statement to check if jj==jj+(2**(level+1))
Obviously, you need to be careful as a high max number may increase your worst case delay and the minimum clock cycle time.

//ll,level,K has to be declare.
always# (posedge y_ndd[0] or posedge J)
begin
if(J==1'b1)
begin
for (idx=0; idx<N/2; idx=idx+1)
begin
IN[2*idx] <= X[idx*2*X_WDTH+: 2*X_WDTH];
IN[2*idx+1] <= X[(idx+N/2)*2*X_WDTH+: 2*X_WDTH];
end
end
else
begin
ll=ll+1;
modulecount=0;
for(level=0;level<K;level=level+1) //K time you need to execute
begin
if(ll==level)
begin
for(jj=0;jj<N;jj=jj+(2**(level+1)))
begin
for (jx=jj; jx<jj+(2**level); jx=jx+1)
begin
IN[modulecount] <=OUT[jx];
IN[modulecount+1] <=OUT[jx+(2**level)];
modulecount=modulecount+1;
end
end
end
end
//ll=ll+1;
end
end
You can try this. It has to work. But problem is outer loop will execute K times.

Related

Is there a way of manipulating a global variable you use as an argument for a function in lua?

I'm trying to write some code into a function so that it can be easily reused whereby a global value is increased.
The issue is that there are several different globals that can be manipulated, and I need the function to be able to handle each one.
I thought I could simply put the global variable into the argument in the function but it doesn't seem to work. Probably because lua creates a copy of the global variable it takes.
Is there a way to make sure that the global variable it manipulates is not just a copy?
I have already tried to make sure that all the relevant variables remain local, but the problem is that they are all in a loop, and so need to remain outside the loop to be able to increment properly.
Right now I have to write a separate function for each case of incrementation which is a little unweildy, if bareable.
Right now I have to do something like this
foo_time_1 = 0
foo_time_2 = 0
function foo_time_1(var)
foo_time_1 += 2
if foo_time < 2 then
sfx(02)
end
end
function foo_time_2(var)
if foo_time_2 < 2 then
sfx(02)
end
end
This allows the code to run as intended, but Ideally I would like the code to look something like this:
foo_time = 0
foo_time_2 = 0
function foo_time_manipulator(global_var, len, sfx)
global_var += 2
if global_var < len then
play(sfx)
end
end
//so I can write
foo_time_manipulator(foo_time, 2, 02)
foo_time_manupulator(foo_time_2, 3, 02)
The problem with that is that the global variable doesn't change and so the sound effect loops continuously as every frame the function is re-read and it see that the global varaible remains at the value it was used as an argument, rather than the updated variable.
Sorry if this question has been poorly worded, it's a little difficult to articulate.
Is there any way in lua to be able to manipulate a global variable that is used as an argument?
A good qualifier may be that this code is being looped, and so requires an outside variable to act as a counter.
You can try this:
function foo_time_manipulator(global_var_name, len, six)
local global_var = _G[global_var_name]
global_var = global_var + 2
if global_var < len then
play(sfx)
end
end
and use it like this
foo_time_manipulator("foo_time", 2, 02)
foo_time_manupulator("foo_time_2", 3, 02)

How to improve performance for REGEXP string matching in MySQL?

Preface:
I've done quite a bit of (re)searching on this, and found the following SO post/answer: https://stackoverflow.com/a/5361490/6095216 which was pretty close to what I'm looking for. The same code, but with somewhat more helpful comments, appears here: http://thenoyes.com/littlenoise/?p=136 .
Problem Description:
I need to split 1 column of MySQL TEXT data into multiple columns, where the original data has this format (N <= 7):
{"field1":"value1","field2":"value2",...,"fieldN":"valueN"}
As you might guess, I only need to extract the values, putting each one into a separate (predefined) column. The problem is that the number and order of the fields is not guaranteed to be the same for all records. Thus, solutions using SUBSTR/LOCATE, etc. don't work, and I need to use regular expressions. Another restriction is that 3rd party libraries such as LIB_MYSQLUDF_PREG (suggested in the answer from my 1st link above) cannot be used.
Solution/Progress so far:
I've modified the code from the above links such that it returns the first/shortest match, left-to-right; otherwise, NULL is returned. I also refactored it a bit and made the identifiers more reader/maintainer-friendly :)
Here's my version:
CREATE FUNCTION REGEXP_EXTRACT_SHORTEST(string TEXT, exp TEXT)
RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE adjustStart, adjustEnd BOOLEAN DEFAULT TRUE;
DECLARE startInd INT DEFAULT 1;
DECLARE endInd, strLen INT;
DECLARE candidate TEXT;
IF string NOT REGEXP exp THEN
RETURN NULL;
END IF;
IF LEFT(exp, 1) = '^' THEN
SET adjustStart = FALSE;
ELSE
SET exp = CONCAT('^', exp);
END IF;
IF RIGHT(exp, 1) = '$' THEN
SET adjustEnd = FALSE;
ELSE
SET exp = CONCAT(exp, '$');
END IF;
SET strLen = LENGTH(string);
StartIndLoop: WHILE (startInd <= strLen) DO
IF adjustEnd THEN
SET endInd = startInd;
ELSE
SET endInd = strLen;
END IF;
EndIndLoop: WHILE (endInd <= strLen) DO
SET candidate = SUBSTRING(string FROM startInd FOR (endInd - startInd + 1));
IF candidate REGEXP exp THEN
RETURN candidate;
END IF;
IF adjustEnd THEN
SET endInd = endInd + 1;
ELSE
LEAVE EndIndLoop;
END IF;
END WHILE EndIndLoop;
IF adjustStart THEN
SET startInd = startInd + 1;
ELSE
LEAVE StartIndLoop;
END IF;
END WHILE StartIndLoop;
RETURN NULL;
END;
I then added a helper function to avoid having to repeat the regex pattern, which, as you can see from above, is the same for all the fields. Here is that function (I left my attempt to use a lookbehind - unsupported in MySQL - as a comment):
CREATE FUNCTION GET_MY_FLD_VAL(inputStr TEXT, fldName TEXT)
RETURNS TEXT DETERMINISTIC
BEGIN
DECLARE valPattern TEXT DEFAULT '"[^"]+"'; /* MySQL doesn't support lookaround :( '(?<=^.{1})"[^"]+"'*/
DECLARE fldNamePat TEXT DEFAULT CONCAT('"', fldName, '":');
DECLARE discardLen INT UNSIGNED DEFAULT LENGTH(fldNamePat) + 2;
DECLARE matchResult TEXT DEFAULT REGEXP_EXTRACT_SHORTEST(inputStr, CONCAT(fldNamePat, valPattern));
RETURN SUBSTRING(matchResult FROM discardLen FOR LENGTH(matchResult) - discardLen);
END;
Currently, all I'm trying to do is a simple SELECT query using the above code. It works correctly, BUT IT. IS. SLOOOOOOOW... There are only 7 fields/columns to split into, max (not all records have all 7)! Limited to 20 records, it takes about 3 minutes - and I have about 40,000 records total (not very much for a database, right?!) :)
And so, finally, we get to the actual question: [how] can the above algorithm/code (pretty much a brute search at this point) be improved SIGNIFICANTLY performance-wise, such that it can be run on the actual database in a reasonable amount of time? I started looking into the major known pattern-matching algorithms, but quickly got lost trying to figure out what would be appropriate here, in large part due to the number of available options and their respective restrictions, conditions for use, etc. Plus, it seems like implementing one of these in SQL just to see if it would help, might be a lot of work.
Note: this is my first post ever(!), so please let me know (nicely) if something is not clear, etc. and I will do my best to fix it. Thanks in advance.
I was able to solve this by parsing the JSON, as suggested by tadman and Matt Raines above. Being new to the concept of JSON, I just didn't realize it could be done this way at all...a little embarrassing, but lesson learned!
Anyway, I used the get_option function in the common_schema framework: https://code.google.com/archive/p/common-schema/ (found through this post, which also demonstrates how to use the function: Parse JSON in MySQL ). As a result, my INSERT query took about 15 minutes to run, vs the 30+ hours it would've taken with the REGEXP solution. Thanks, and until next time! :)
Don't do it in SQL; do it in PHP or some other language that has builtin tools for parsing JSON.

MySql Procedure GOTO Statement

I want to use goto statement in Mysql stored procedure in such manner that I execute my cursor whenever condition become true once again.
This is a sample code only, I just looking for goto statement
BLOCK_BACKLOG:begin
declare backlgId, oldCOR, oldATR,oldCourse,oldATR,isFormFilled,nextParentId int;
declare backlogNoMoreRow boolean default false;
Label : TestLineStart
declare backlogCur cursor for select bcklg.id,cor.id,atr.id,cr.id,atr.obtainedMarks,atr.isFormFilled,atr.parentRegistration_id
from train bcklg,bus cor,fliet atr,fair co,distance cr
where bcklg.courseofferingregistration_id=cor.id and cor.academictermregistration_id=atr.id and cor.courseoffering_id=co.id and co.course_id=cr.id
and bcklg.isDeleted is false and atr.id=parentId;
declare continue handler for not found set backlogNoMoreRow=true;
open backlogCur;
LOOP_BACKLOG: loop
fetch backlogCur into backlgId, oldCOR, oldATR,oldCourse,oldATRMarks,isFormFilled,nextParentId;
if backlogNoMoreRow then
close backlogCur;
leave LOOP_BACKLOG;
end if;
if isFormFilled==0 then
parentId=nextParentId;
GOTO TestLineStart;
end if;
You can use a LOOP on the outer block based on the value for variable isFormFilled.
Following change may help you.
-- Label : TestLineStart
TestLineStart: LOOP
-- other part of your SP as it is
and make following change:
if isFormFilled==0 then
parentId=nextParentId;
-- GOTO TestLineStart;
else
leave TestLineStart;
end if;
You have to close all loop statements properly.

How to use goto label in MySQL stored function

I would like to use goto in MySQL stored function.
How can I use?
Sample code is:
if (action = 'D') then
if (rowcount > 0) then
DELETE FROM datatable WHERE id = 2;
else
SET p=CONCAT('Can not delete',#b);
goto ret_label;
end if;
end if;
Label: ret_label;
return 0;
There are GOTO cases which can't be implemented in MySQL, like jumping backwards in code (and a good thing, too).
But for something like your example where you want to jump out of everything to a final series of statements, you can create a BEGIN / END block surrounding the code to jump out of:
aBlock:BEGIN
if (action = 'D') then
if (rowcount > 0) then
DELETE FROM datatable WHERE id = 2;
else
SET p=CONCAT('Can not delete',#b);
LEAVE aBlock;
end if;
end if;
END aBlock;
return 0;
Since your code is just some nested IFs, the construct is unnecessary in the given code. But it makes more sense for LOOP/WHILE/REPEAT to avoid multiple RETURN statements from inside a loop and to consolidate final processing (a little like TRY / FINALLY).
There is no GOTO in MySQL Stored Procs. You can refer to this post:
MySQL :: Re: Goto Statement

Check if anniversary month is within a range of months

I'm trying to execute some different logic in a stored procedure when processing the anniversary month. Using a simple IF(anniversary = MONTH(x)) works fine when only one month is processed.
However, when multiple months are processed, the differing logic needs to be executed if the anniversary month is between the start month and the end month. IF(anniversary BETWEEN MONTH(x) AND MONTH(y)) will not work over the new year (i.e. September–January).
The anniversary field is currently generated as MONTH(contract_start), but this can be changed (it was previously using MONTHNAME() before, I have no idea why).
I was thinking that it might be a good idea for anniversary to become a boolean, to make the IF function more readable.
Okay, I worked this out. It was simple once I wrote down the algoritm in pseudocode
I've created a function to store the logic instead, but it's fairly easy to turn it into an expression if needed.
BEGIN
IF min != max
THEN
IF YEAR(min) != YEAR(max)
THEN
IF MONTH(born) BETWEEN MONTH(min) AND 12
OR MONTH(born) BETWEEN 1 AND MONTH(max)
THEN RETURN 1;
ELSE RETURN 0;
END IF;
ELSEIF MONTH(born) BETWEEN MONTH(min) AND MONTH(max)
THEN RETURN 1;
ELSE RETURN 0;
END IF;
ELSEIF MONTH(born) = MONTH(min)
THEN RETURN 1;
ELSE RETURN 0;
END IF;
END