How can I make a ternary condition in SpinalHDL? - fpga

I would like to make a ternary condition in SpinalHDL as a ternary assignment in Verilog:
e.g.
wire my_condition = (this == that);
wire [1:0] my_ternary_wire = my_condition ? 2'b10 : 2'b01;
desired SpinalHDL code:
val myCondition = this === that
val myTernaryWire = myCondition ? B(3) : B(1)

I just saw it is possible to use:
val myCondition = this === that
val myTernaryWire = myCondition ? B(3) | B(1)
just changing : to |

Related

How to turn an integer into a string in ATS?

I am in need of a function, say, int2string, that can convert a given integer into its string representation. If possible, int2string may take a second argument referring to the base of the representation. By default, this second argument is 10.
To tostring_int. It's available in prelude/SATS/tostring.sats and you can overload tostring or something if you'd like :)
This works - although it may not be the best style. Please feel free to refine this answer.
extern
fun
int2string(i: int, b: int): string
(* ****** ****** *)
implement
int2string(i, b) = let
val () = assertloc(i >= 0)
fun dig2str(i:int): string =
if i = 0 then "0"
else if i = 1 then "1"
else if i = 2 then "2"
else if i = 3 then "3"
else if i = 4 then "4"
else if i = 5 then "5"
else if i = 6 then "6"
else if i = 7 then "7"
else if i = 8 then "8"
else if i = 9 then "9"
else "" // can add A, B, C,...
fun helper(i: int, res: string): string =
if i > 0 then helper(i / b, dig2str(i % b) + res)
else res
in
helper(i, "")
end

Unable to use enum in systemverilog

I have a design file ALU and another testbench. Here is my code:
parameter WIDHT = 4;
typedef enum logic[1:0] {
ADD =2'b00,
AND =2'b01,
OR = 2'b10,
XOR = 2'b11
} operation;
module ALU
(
input logic [WIDHT-1:0] A,B,
input operation op,
output logic [WIDHT-1:0] R,
output logic N,Z,V
);
always_comb
begin
unique case(op)
ADD: R = A+B;
AND: R = A&B;
OR: R = A|B;
XOR: R = A^B;
default : R=0;
endcase
if(R=='b0)
Z = 1;
else if (R[WIDHT-1] == 1'b1)
begin
if( A[WIDHT-1] == 1'b0 && B[WIDHT-1] == 1'b0)
V = 1;
else
N = 1;
end
else if (R[WIDHT-1] == 1'b0)
begin
if( A[WIDHT-1] == 1'b1 && B[WIDHT-1] == 1'b1)
V = 1;
else
begin
R=0;
Z=0;
V=0;
end
end
end
endmodule: ALU
Here is my testbench:
parameter W = 4;
module ALU_tb;
logic [W-1:0] A,B;
logic [1:0] op1;
logic [W-1:0] R;
logic N,Z,V;
ALU alu(A,B,op1,R,N,Z,V);
initial
begin
$monitor($time," A = %b, B = %b, ope = %b, R = %b, N = %b, Z = %b, V = %b",A,B,op1,R,N,Z,V);
A =0;
B=0;
#10;
for(A=0; A<2**W ; A++)
begin
for(B=0; B<'d2**W ; B++)
begin
/*for(op = op.first; op<=op.last; op.next)
#10; */
for(op1 = 2'b00; op1<=2'b11; op1++)
#10;
end
end
end
endmodule: ALU_tb
Now, the code compiles successfully but doesn't simulate. It gives me an error saying that I need to assign an enum to the same enum type or one of its value. What is that I am doing wrong? Any suggestions? One thing I found was to use packages and put the typedef enum in it and then import the package in both my design and testbench files. But I am trying to avoid using enum in my testbench. Can someone suggest something?
An enum is a stronger type than most integral types. You need use the package method to make the types assignment compatible.
Another option is making your port a bit-vector, and then casting it to operation type inside your design.

How do I prove that c-'a' is within [0,26)?

Suppose I have this code:
#include "share/atspre_staload.hats"
val letters = arrayref_make_elt<bool>(i2sz(26), false)
implement main0() =
begin
println!("found('a'): ", letters[0]);
println!("found('f'): ", letters[5]);
end
Which produces the output:
found('a'): false
found('f'): false
I'd like to index into letters by character, instead. Actually, given any character I'd like to index into letters only if it's a valid index.
So this almost works:
#include "share/atspre_staload.hats"
val letters = arrayref_make_elt<bool>(i2sz(26), false)
typedef letter = [c:int | c >= 'a' && c <= 'z'] char(c)
typedef letteri = [i:int | i >= 0 && i < 26] int(i)
(* fn letter2index(c: letter): letteri = c - 'a' *) (* #1 *)
fn letter2index(c: letter): letteri =
case- c of
| 'a' => 0
| 'f' => 5
fn trychar(c: char): void = (* #2 *)
if c >= 'a' && c <= 'z' then
println!("found('", c, "'): ", letters[letter2index(c)])
implement main0() =
begin
trychar('a');
trychar('f');
trychar('+'); (* #3 *)
end
If I change char to letter at #2 and remove trychar('+') at #3, then this compiles. But of course I'd rather perform subtraction at #1 rather than have a big case of letters, and I'd to apply trychar to any kind of char, not just a letter.
The code you want can be written as follows:
#include
"share/atspre_staload.hats"
stadef
isletter(c:int): bool = ('a' <= c && c <= 'z')
val
letters = arrayref_make_elt<bool>(i2sz(26), false)
fn
letter2index
{ c:int
| isletter(c)}
(c: char(c)): int(c-'a') = char2int1(c) - char2int1('a')
fn
trychar
{c:int}
(c: char(c)): void =
if
(c >= 'a') * (c <= 'z')
then
println!("found('", c, "'): ", letters[letter2index(c)])
implement main0() =
begin
trychar('a');
trychar('f');
trychar('+');
end
In your original code, quantifiers (forall and exists) were not used correctly.

Algorithm to check matching parenthesis

This relates to the Coursera Scala course so I want to directly ask you NOT to give me the answer to the problem, but rather to help me debug why something is happening, as a direct answer would violate the Coursera honor code.
I have the following code:
def balance(chars: List[Char]): Boolean = {
val x = 0
def loop(list: List[Char]): Boolean = {
println(list)
if (list.isEmpty) if(x == 0) true
else if (list.head == '(') pushToStack(list.tail)
else if (list.head == ')') if(x <= 0) false else decreaseStack(list.tail)
else loop(list.tail)
true
}
def pushToStack(myList: List[Char]) { x + 1; loop(myList)}
def decreaseStack(myList: List[Char]) { x - 1; loop(myList)}
loop(chars)
}
A simple explanation:
If the code sees a "(" then it adds 1 to a variable. If it sees a ")" then it first checks whether the variable is equal to or smaller than 0. If this is the case, it returns false. If the value is bigger than 0 then it simply decreases one from the variable.
I have tried running the following:
if(balance("This is surely bad :-( ) (".toList)) println("balanced") else println("not balanced");
Clearly this is not balanced, but my code is returning balanced.
Again: I am not asking for help in writing this program, but rather help in explained why the code is returning "balanced" when clearly the string is not balanced
--EDIT--
def balance(chars: List[Char]): Boolean = {
val temp = 0;
def loop(list: List[Char], number: Int): Boolean = {
println(list)
if (list.isEmpty) if(number == 0) true
else if (list.head == '(') loop(list.tail, number + 1)
else if (list.head == ')') if(number <= 0) false else loop(list.tail, number - 1)
else loop(list.tail,number)
true
}
loop(chars,0)
}
^^ Still prints out balanced
You are using an immutable x when you really want a mutable x.
Here, let me rewrite it for you in a tail recursive style to show you what you're actually doing:
#tailrec def loop(myList: List[Char], cur: Int = 0): Boolean = myList match{
case "(" :: xs =>
val tempINeverUse = cur+1
loop(xs, cur) //I passed in 0 without ever changing "cur"!
case ")" :: xs if cur < 0 => false //This is a bug, regardless if you fix the rest of it
case ")" :: xs =>
val tempINeverUse = cur-1
loop(xs, cur) //Passed in 0 again!
case x :: xs => loop(xs, cur)
case Nil => cur == 0 //Since I've never changed it, it will be 0.
}
You need to keep a context of parenthesis in comments or in quotes as well. You can use a counter to achieve that. If the counter is set for a comment or a double quote then ignore any parenthesis that comes your way. Reset the counter whenever you find a finishing comment or double quote

Turn this if-then logic into a boolean expression?

I'm having a bit of a brain fart on making this code more concise(preferably a single boolean expression)
This is my code:
if (d.Unemployed)
{
if (type.Unemployed)
{
tmp.Unemployed = true;
}
else
{
tmp.Unemployed = false;
}
}
else
{
if (type.Unemployed)
{
tmp.Unemployed = false;
}
else
{
tmp.Unemployed = true;
}
}
Basically the point is that if either type or d is not unemployed, then tmp should be set to not unemployed.
How about:
tmp.Unemployed = type.Unemployed == d.Unemployed;
If we construct a truth table by following the code, we get
d | type | tmp
---+------+----
1 | 1 | 1
---+------+----
1 | 0 | 0
----+-----+----
0 | 1 | 0
----+-----+----
0 | 0 | 1
The above is equivalent with the negation of the xor operation.
tmp = not (d xor type)
If the language doesn't have the xor operator we can use the != on boolean values.
tmp = ! (d != type);
// or
tmp = d == type;
Thinking about how much "brain fart" this caused you I would consider using a well named variable to avoid having to go through this mental process again in future. Something like this:
isTmpUnemployed = (type.Unemployed == d.Unemployed);
tmp.Unemployed = isTmpUnemployed;
The above code means "both unemployed or both not unemployed". Thus, not (A xor B):
tmp.Unemployed = ! ( D.Unemployed ^ type.Unemployed)
tmp.Unemployed = d.Unemployed || type.Unemployed ? !tmp.Unemployed : null;

Resources