Recursion in Verilog within an Always block - recursion

I have a verilog code where I wish to use recursion. However, whenever I try this in an always block, it gives an error saying is not a task.
Is there any way I can implement a module in an always block? Also is there anyway I can use recursion within the always block?

You can write recursive modules using a generate block:
module unary_and
#(parameter WIDTH = 32)
(input [WIDTH-1:0] in_and,
output out_and)
generate
if(WIDTH == 1) begin
assign out_and = in_and;
end
else if(WIDTH == 2) begin
assign out_and = in_and[0] & in_and[1];
end
else begin
unary_and #(.WIDTH (WIDTH/2))
unary_and_low
(.in_and (in_and[WIDTH/2-1:0]),
.out_and (out_and_low));
unary_and #(.WIDTH (WIDTH - WIDTH/2))
unary_and_high
(.in_and (in_and[WIDTH-1:WIDTH/2]),
.out_and (out_and_high));
assign out_and = out_and_low & out_and_high;
end
endgenerate
endmodule
This is from Recursive and Iterative designs in Verilog where you can find other solutions as well. You can check out Recursive Modules too.
Maybe you should also take a look at these questions and answers:
Could we have generate inside an always block?
Verilog generate/genvar in an always block

Related

How do I pass a variable to a macro and evaluate it before macro execution?

If I have a method
macro doarray(arr)
if in(:head, fieldnames(typeof(arr))) && arr.head == :vect
println("A Vector")
else
throw(ArgumentError("$(arr) should be a vector"))
end
end
it works if I write this
#doarray([x])
or
#doarray([:x])
but the following code rightly does not work, raising the ArgumentError(i.e. ArgumentError: alist should be a vector).
alist = [:x]
#doarray(alist)
How can I make the above to act similarly as #doarray([x])
Motivation:
I have a recursive macro(say mymacro) which takes a vector, operates on the first value and then calls recursively mymacro with the rest of the vector(say rest_vector). I can create rest_vector, print the value correctly(for debugging) but I don't know how to evaluate rest_vector when I feed it to the mymacro again.
EDIT 1:
I'm trying to implement logic programming in Julia, namely MiniKanren. In the Clojure implementation that I am basing this off, the code is such.
(defmacro fresh
[var-vec & clauses]
(if (empty? var-vec)
`(lconj+ ~#clauses)
`(call-fresh (fn [~(first var-vec)]
(fresh [~#(rest var-vec)]
~#clauses)))))
My failing Julia code based on that is below. I apologize if it does not make sense as I am trying to understand macros by implementing it.
macro fresh(varvec, clauses...)
if isempty(varvec.args)
:(lconjplus($(esc(clauses))))
else
varvecrest = varvec.args[2:end]
return quote
fn = $(esc(varvec.args[1])) -> #fresh($(varvecvest), $(esc(clauses)))
callfresh(fn)
end
end
end
The error I get when I run the code #fresh([x, y], ===(x, 42))(you can disregard ===(x, 42) for this discussion)
ERROR: LoadError: LoadError: UndefVarError: varvecvest not defined
The problem line is fn = $(esc(varvec.args[1])) -> #fresh($(varvecvest), $(esc(clauses)))
If I understand your problem correctly it is better to call a function (not a macro) inside a macro that will operate on AST passed to the macro. Here is a simple example how you could do it:
function recarray(arr)
println("head: ", popfirst!(arr.args))
isempty(arr.args) || recarray(arr)
end
macro doarray(arr)
if in(:head, fieldnames(typeof(arr))) && arr.head == :vect
println("A Vector")
recarray(arr)
else
throw(ArgumentError("$(arr) should be a vector"))
end
end
Of course in this example we do not do anything useful. If you specified what exactly you want to achieve then I might suggest something more specific.

PL/SQL annoymous procedure + cursor problems

I am trying to write an anonymous block as follows, but it always give me error messages as
Encountered the symbol "=" when expecting one of the following. ( ) , * # % & - + / at mod remainder rem and or || multiset.
I don't know what it means.
You're missing a : in front of the =in several places, e.g. here:
get_sectno='1031';
The assignment operator in PL/SQL is :=- = is (just like in plain SQL) comparison for equality.
You're also missing the ; at the end of every call to
lowest_average (get_term, get_sectno, get_ctitle, get_sid, get_sname, get_average)

Recursively wrapping up an element

Say I have an element <x>x</x> and some empty elements (<a/>, <b/>, <c/>), and I want to wrap up the first inside the second one at a time, resulting in <c><b><a><x>x</x></a></b></c>. How do I go about this when I don't know the number of the empty elements?
I can do
xquery version "3.0";
declare function local:wrap-up($inner-element as element(), $outer-elements as element()+) as element()+ {
if (count($outer-elements) eq 3)
then element{node-name($outer-elements[3])}{element{node-name($outer-elements[2])}{element{node-name($outer-elements[1])}{$inner-element}}}
else
if (count($outer-elements) eq 2)
then element{node-name($outer-elements[2])}{element{node-name($outer-elements[1])}{$inner-element}}
else
if (count($outer-elements) eq 1)
then element{node-name($outer-elements[1])}{$inner-element}
else ($outer-elements, $inner-element)
};
let $inner-element := <x>x</x>
let $outer-elements := (<a/>, <b/>, <c/>)
return
local:wrap-up($inner-element, $outer-elements)
but is there a way to do this by recursion, not decending and parsing but ascending and constructing?
In functional programming, you usually try to work with the first element and the tail of a list, so the canonical solution would be to reverse the input before nesting the elements:
declare function local:recursive-wrap-up($elements as element()+) as element() {
let $head := head($elements)
let $tail := tail($elements)
return
element { name($head) } { (
$head/#*,
$head/node(),
if ($tail)
then local:recursive-wrap-up($tail)
else ()
) }
};
let $inner-element := <x>x</x>
let $outer-elements := (<a/>, <b/>, <c/>)
return (
local:wrap-up($inner-element, $outer-elements),
local:recursive-wrap-up(reverse(($inner-element, $outer-elements)))
)
Whether reverse(...) will actually require reversing the output or not will depend on your XQuery engine. In the end, reversing does not increase computational complexity, and might not only result in cleaner code, but even faster execution!
Similar could be achieved by turning everything upside down, but there are no functions for getting the last element and everything before this, and will possibly reduce performance when using predicates last() and position() < last(). You could use XQuery arrays, but will have to pass counters in each recursive function call.
Which solution is fastest in the end will require benchmarking using the specific XQuery engine and code.

Ada sin(x) Computing with Taylor-series

I'm an absolute beginner in Ada and I'm trying to calculate sin(x) [sin(3) now] by using Taylor-series, but I just can't get it to work.
So here is my procedure:
with Ada.Float_Text_IO;
with Mat;
procedure SinKoz is
X:Float:=3.0;
Szamlalo:Float:=0.0;
begin
for I in 1..100 loop
Szamlalo := Szamlalo + ((-1.0)**I)*(X**(2.0*I+1.0))/Mat.Faktorialis(2*I+1);
end loop;
Ada.Float_Text_IO.Put( Szamlalo );
end SinKoz;
And inside Mat, here is my Faktorialis, which calculates the factorial of 2*I+1:
function Faktorialis( N: Float ) return Float is
Fakt : Float := 1.0;
begin
for I in 1..N loop
Fakt := Fakt * I;
end loop;
return Fakt;
end Faktorialis;
When i'm trying to compile my code, this error comes up:
exponent must be of type Natural, found type "Standard.Float"
I hope you can help me trying to figure out what went wrong with my types!
The first question is : do you need to raise X to a non-integer power?
It looks to me as if you don't : in which case replace X**(2.0*I+1.0) with X**(2*I+1) and all will be well.
But if you really do (perhaps not here, but in another application) you just need to make such an operator visible : there's one for Float in the package Ada.Numerics.Elementary_Functions so precede your function with
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;
and it should work as written.
Finally, if you have created your own float type, you can instantiate the generic package Ada.Numerics.Generic_Elementary_Functions with your type as its parameter, to create a set of these functions specifically for your type.
Gotta love Ada's strong typing.
Off the top of my head, I suspect your problem may be this line:
Szamlalo := Szamlalo + ((-1.0)**I)*(X**(2.0*I+1.0))/Mat.Faktorialis(2*I+1);
2.0*I+1.0 is going to return a Float. Not a Natural. You could try wrapping that in Integer() or Natural() (Natural is a subtype of Integer) and see if that helps.

Ada String Concatenation

I have a function that returns a string for a particular item, and I need to call that function numerous times and combine those strings into one. The combined string is bounded. I've made sure to fill it when space characters when it initializes but I keep getting "length check failed" errors. Is there something basic I'm doing wrong here?
FOR I IN 1..Collection.Size LOOP
Combined_String := combined_string & Tostring(Collection.Book(I));
END LOOP;
Unbounded_String is probably the easiest way to go:
with Ada.Strings.Unbounded;
use Ada.Strings.unbounded;
...
Temp_Unbounded_String : Unbounded_String; -- Is empty by default.
...
for I in 1 .. Collection.Size loop
Append(Temp_Unbounded_String, ToString(Collection.Book(I));
end loop;
If you then need to have the result placed in your fixed length standard string:
declare
Temp_String : constant String := To_String(Temp_Unbounded_String);
begin
-- Beware! If the length of the Temp_String is greater than that of the
-- fixed-length string, a Constraint_Error will be raised. Some verification
-- of source and target string lengths must be performed!
Combined_String(Temp_String'Range) := Temp_String;
end;
Alternatively, you can use the Ada.Strings.Fixed Move() procedure to bring the Unbounded_String into the target fixed-length string:
Ada.Strings.Fixed.Move(To_String(Temp_Unbounded_String), Combined_String);
In this case, if the source string is "too long", by default a Length_Error exception is raised. There are other parameters to Move() that can modify the behavior in that situation, see the provided link on Move for more detail.
In order to assign Combined_String, you must assign the full correct length at once. You can't "build up" a string and assign it that way in Ada.
Without seeing the rest of your code, I think Ada.Strings.Unbounded is probably what you should be using.
I know this is an ancient question, but now that Ada 2012 is out I thought I'd share an idiom I've been finding myself using...
declare
function Concatenate(i: Collection'index)
is
(tostring(Collection(i) &
if (i = Collection'last) then
("")
else
(Concatenate(i+1))
);
s: string := Concatenate(Collection'first);
begin
Put_Line(s);
end;
Typed off the top of my head, so it'll be full of typos; and if you want it to work on empty collections you'll need to tweak the logic (should be obvious).
Ada 2012's expression functions are awesome!
Ada works best when you can use perfectly-sized arrays and strings. This works wonderfully for 99% of string uses, but causes problems any time you need to progressively build a string from something else.
Given that, I'd really like to know why you need that combined string.
If you really need it like that, there are two good ways I know of to do it. The first is to use "unbounded" (dynamically-sized) strings from Ada.Strings.Unbounded, as Dave and Marc C suggested.
The other is to use a bit of functional programming (in this case, recursion) to create your fixed string. Eg:
function Combined_String (String_Collection : in String_Collection_Type) return String is
begin
if String_Collection'length = 1 then
return String_Collection(String_Collection'first);
end if;
return String_Collection(String_Collection'first) &
Combined_String (String_Collection'first + 1 .. String_Collection'last);
end Combined_String;
I don't know what type you used for Collection, so I'm making some guesses. In particular, I'm assuming its an unconstrained array of fixed strings. If it's not, you will need to replace some of the above code with whatever your container uses to return its bounds, access elements, and perform slicing.
From AdaPower.com:
function Next_Line(File : in Ada.Text_IO.File_Type :=
Ada.Text_Io.Standard_Input) return String is
Answer : String(1..256);
Last : Natural;
begin
Ada.Text_IO.Get_Line(File => File,
Item => Answer,
Last => Last);
if Last = Answer'Last then
return Answer & Next_Line(File);
else
return Answer(1..Last);
end if;
end Next_Line;
As you can see, this method builds a string (using Get_Line) of unlimited* length from the file it's reading from. So what you'll need to do, in order to keep what you have is something on the order of:
function Combined_String (String_Collection : in String_Collection_Type)
Return String is
begin
if String_Collection'length = 1 then
Return String_Collection(String_Collection'First).All;
end if;
Recursion:
Declare
Data : String:= String_Collection(String_Collection'First).All;
SubType Constraint is Positive Range
Positive'Succ(String_Collection'First)..String_Collection'Last;
Begin
Return Data & Combined_String( String_Collection(Constraint'Range) );
End Recursion;
end Combined_String;
Assuming that String_Collection is defined as:
Type String_Collection is Array (Positive Range <>) of Access String;
*Actually limited by Integer'Range, IIRC

Resources