Error message ”sorry: constant selects in always_* processes are not currently supported (all bits will be included).“ in SystemVerilog - case

I need to use "case" statement to implement a 4-bit priority encoder,and the code is showed below:
module case2(
input [3 : 0] in,
output logic [1 : 0] pos
);
always_comb begin
case(1)
in[0]:pos=2'b00;
in[1]:pos=2'b01;
in[2]:pos=2'b10;
in[3]:pos=2'b11;
default:pos=2'b00;
endcase
end
endmodule
It seems that I can't use '1' as a expr of case in the always_comb block.I have searched in google,but nothing helpful is acquired.How can I solve this problem?Is constant can not be used as a expr of case?I think it's unreasonable.
Thanks for your advice!

"Not currently supported" means the tool believes the code is valid, but they have not implemented it yet. You did not say what tool you are using.
There is always the brute force approach:
always_comb
case(in)
4'b0001,4'b0011, ... 4'b1111 :pos=2'b00;
4'b0010,4'b0110, 4'b1010,4'b1110 :pos=2'b01;
4'b0100,4'b1100 :pos=2'b10;
4'b1000 :pos=2'b11;
default :pos=2'b00;
endcase
Another way you can write this is with a priority if statement
always_comb
priority if (in[0]) pos=2'b00;
else if (in[1]) pos=2'b01;
else if (in[2]) pos=2'b10;
else if (in[3]) pos=2'b11;
else pos=2'b00;

Related

Pascal linked list to linked list does not work

These are two linked lists that I've made,for a school project...
I want the first list to be called from the second,I have done that and at the compile time everything is ok. When I run it it says :
Project (myProject) raised exception class 'External: SIGSEGV'.
At address 40D32D
Here is my code:
list2=^ptr;
ptr=record
vlera:integer;
pozicioni:integer;
end;
type
list=^pointer;
pointer=record
rreshti:list2;
end;
var
a:array[1..7] of list;
i:integer;
kjovlere:list2;
begin
for i:=1 to 7 do begin
a[i]:=#kjovlere;
write('Give the pozition for the row:',i,' : ');
read(a[i]^.rreshti^.pozicioni);
write ('give the value for this poziton :');
read(a[i]^.rreshti^.vlera);
writeln;
end;
end.
And the error is at the for loop,at the read(a[i]^.rreshti^.pozicioni);
I would be very thankful if anyone explains me or gives me any suggestion :)
The provided source code shows at least two misunderstandings about pointer management in Pascal.
Main Problem - To assign data, a record type shall be allocated before.
This problem is referring to the lines read(a[i]^.rreshti^.pozicioni); and read(a[i]^.rreshti^.vlera);.
Both a[i] and rreshti are declared as pointer type (list=^pointer; & list2=^ptr;) and shall be allocated to a record structure before assigning data.
Step1: allocate the a[i] pointer in the loop.
new(a[i]);
Step2: allocate the a[i]^.rreshti pointer in the loop.
new(a[i]^.rreshti);
Strange Problem - Assign a pointer to a record type shall respect the destination type.
This problem is referring to the line a[i]:=#kjovlere;.
The a[i] is a list which is list=^pointer; and not list2 (list2=^ptr;) as declared for kjovlere:list2;.
Solution is: remove that line a[i]:=#kjovlere;.
Solution:
begin
for i:=1 to 7 do begin
(* a[i]:=#kjovlere; to be removed *)
new(a[i]);
new(a[i]^.rreshti);
write('Give the pozition for the row:',i,' : ');
read(a[i]^.rreshti^.pozicioni);
write ('give the value for this poziton :');
read(a[i]^.rreshti^.vlera);
writeln;
end;
end.

Implementing Fermat Attack using Maple

I am trying to implement Fermat Attack in maple but it is giving me an error stating that Error,(unexpected. Super beginner with Maple so if anyone who does have some experience could help, it would be much appreciated.
Also, I am trying to factor an integer that is 125 digits long. Does anyone know any efficient algorithm in Maple or any other program that can handle and factor such a large integers?
FermatAtttack:=proc(n::And(posint,odd), maxnumsteps::posint:=10^7,(numsteps::truefalse:=false))
local x, k, r, i, y:
x:=isqrt(n);
if x^2 < n then
x:= x+1
end if;
k:=2*x+1;
r:=x^2-n;
for i to maxnumsteps while not issqr(r) do
r:=r+k;
k:=k+2
end do;
if issqr(r) then
x:=(k-1)/2;
y:=isqrt(r)
else
error "%1 could not facot in %2 iteratioons", n, maxnumsteps
end if;
if not numsteps then
x-y, x+y
else
x-y, x+y, i
end if;
end proc:
You will need to use the Number Field Sieve to factor your 125-digit integer. See this guide to get started.
The error message is a simple syntax error. Your first line is probably supposed to be
FermatAtttack:=proc(n::And(posint,odd), maxnumsteps::posint:=10^7,{numsteps::truefalse:=false})
Maple uses the command "ifactor" to factor integers.
In your parameter sequence of the definition of your procedure FermatAttack, you have a round-bracketed item within the bracketed parameter declaration, and your error message is due to that.
(numsteps::truefalse:=false)
Change that to either just,
numsteps::truefalse:=false
or to,
{numsteps::truefalse:=false}
according to how you intend on calling it. The second of those is termed a keyword parameter. Here's a short illustration of the difference.
FA := proc( ns::truefalse:=false )
print(ns);
end proc:
FA();
false
FA(true);
true
FB := proc( {ns::truefalse:=false} )
print(ns);
end proc:
FB(); # getting the default value
false
FB( ns=false );
false
FB( ns=true );
true
FB( ns ); # a convenience of type truefalse keyword parameters
true
If you use the keyword parameter approach then note that the passed argument true in the next example doesn't match the keyword (which thus gets its default value).
FB( true );
false

Ada actual for "S" must be a variable

So here is a piece of my body file. I am getting the error "words.adb:75:42: actual for "S" must be a variable".
procedure Remove_Character(S : in out Ustring; C : in Character; Successful : out Boolean) is
begin
for I in 1..length(S) loop
if Element(S, I) = C then
Delete(S, I, I);
Successful := true;
return;
end if;
end loop;
Successful := false;
end Remove_Character;
function Is_Subset(Subset : Ustring; S : Ustring) return Boolean is
Could_Remove : Boolean;
begin
for I in 1..length(Subset) loop
Remove_Character(S , Element(Subset, I), Could_Remove);
if Could_Remove = false then
return false;
end if;
end loop;
return True;
end Is_Subset;
I understand where my error is coming from. Remove_Character uses S : in out Ustring while function Is_Subset uses S : in Ustring.
My question is how do I change the variable from Remove_Character into only an in Ustring?
Sorry if this is a tad jumbled, I'm fairly new to both programming and the site.
You can't, at least not directly.
I don't know what a UString is, but I presume the Delete procedure modifies it. If you changed the declaration of S in Remove_Character to S: in Ustring, you'd presumably get an error on the call to Delete.
The simplest approach I can think of would be to make a copy of S in Is_Subset:
Copy_Of_S: UString := S;
and then pass the (modifiable) copy to Remove_Character.
By "simplest", I mean it makes the smallest change to your existing code. But you should probably consider reorganizing it. Determining whether one UString is a subset of another by modifying one of the strings doesn't seem like the best approach; I'm sure there's a more efficient way to do it.
A minor and irrelevant point: this:
if Could_Remove = false then
is better written as:
if not Could_Remove then

Recursion in Verilog within an Always block

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

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