SystemVerilog assertion for primitive - system-verilog

is there a way to add an assertion for a SystemVerilog primitive or only in the module (cell) wrapping the primitive ? simply adding an assertion does not compile
primitive mux (q, d0, d1, s);
output q;
input s, d0, d1;
table
// d0 d1 s : q
0 ? 0 : 0 ;
1 ? 0 : 1 ;
? 0 1 : 0 ;
? 1 1 : 1 ;
0 0 x : 0 ;
1 1 x : 1 ;
endtable
//assert(s != x) else $error("s has value x"); - add this assertion
endprimitive

The only construct allowed inside a user defined primitive (UDP) is the table. You'll need to wrap the UDP in a module to add anything else.

Related

char inside matlab function

I want to run turnMatrix(30,X) in MATLAB. I get this error message:
Undefined function or variable 'X'.
If I change X to 1 it is successful. My code is below.
function turnMatrix(d,b)
a = d * pi / 180 ;
if b == X % 1
R = [1 0 0 0 ; 0 cos(a) -sin(a) 0 ; 0 sin(a) cos(a) 0 ; 0 0 0 1];
elseif b == Y % 2
R = [cos(a) 0 sin(a) 0 ; 0 1 0 0 ; -sin(a) 0 cos(a) 0 ; 0 0 0 1];
elseif b == Z % 3
R = [1 0 0 0 ; 0 cos(a) -sin(a) 0 ; 0 sin(a) cos(a) 0 ; 0 0 0 1];
end
R
end
It looks like you are really expecting/wanting to specify the second input as a characters/string, that is
turnMatrix(30,'X')
Note the single quotes around 'X', which say that it is literally the character string 'X', not the value of the variable X.
Then inside the function you need
if b == 'X'
elseif b == 'Y'
elseif b == 'Z'
end
That is, compare the value of variable b to the character 'X'. The way you have it, you are trying to compare the value of variable b to the value of variable X, but variable X doesn't exist and hence the error.
Note also, that if you were comparing anything other than a single character (and even in the single character case) you'd be better off using a switch-case construct rather than if-else
switch b
case 'X'
case 'Y'
case 'Z'
end

Boolean Simplification - Q=A.B.(~B+C)+B.C+B

I've been struggling with boolean simplification in class, and took it to practice some more at home. I found a list of questions, but they don't have any answers or workings. This one I'm stuck on, if you could answer clearly showing each step I'd much appreciate:
Q=A.B.(~B+C)+B.C+B
I tried looking for a calculator to give me the answer and then to work out how to get to that, but I'm lost
(I'm new to this)
Edit: ~B = NOT B
I've never done this, so I'm using this site to help me.
A.B.(B' + C) = A.(B.B' + B.C) = A.(0 + B.C) = A.(B.C)
So the expression is now A.(B.C) + B.C + B.
Not sure about this, but I'm guessing A.(B.C) + (B.C) = (A + 1).(B.C).
This equals A.(B.C).
So the expression is now A.(B.C) + B.
As A.(B + C) = B.(A.C), the expression is now B.(A.C) + B, which equals (B + 1).(A.C) = B.(A.C).
NOTE: This isn't complete yet, so please avoid downvoting as I'm not finished yet (posted this to help the OP understand the first part).
Let's be lazy and use sympy, a Python library for symbolic computation.
>>> from sympy import *
>>> from sympy.logic import simplify_logic
>>> a, b, c = symbols('a, b, c')
>>> expr = a & b & (~b | c) | b & c | b # A.B.(~B+C)+B.C+B
>>> simplify_logic(expr)
b
There are two ways to go about such a formula:
Applying simplifications,
Brute force
Let's look at brute force first. The following is a dense truth table (for a better looking table, look at Wα), enumerating all possible value for a, b and c, alongside the values of the expression.
a b c -- a & b & (~b | c) | b & c | b = Q
0 0 0 0 0 10 1 0 0 0 0 0 = 0
0 0 1 0 0 10 1 1 0 0 1 0 = 0
0 1 0 0 1 01 0 0 1 0 0 1 = 1
0 1 1 0 1 01 1 1 1 1 1 1 = 1
1 0 0 1 0 10 1 0 0 0 0 0 = 0
1 0 1 1 0 10 1 1 0 0 1 0 = 0
1 1 0 1 1 01 1 0 1 0 0 1 = 1
1 1 1 1 1 01 1 1 1 1 1 1 = 1
You can also think of the expression as a tree, which will depend on the precedence rules (e.g. usually AND binds stronger than OR, see also this question on math.se).
So the expression:
a & b & (~b | c) | b & c | b
is a disjunction of three terms:
a & b & (~b | c)
b & c
b
You can try to reason about the individual terms, knowing that only one has to be true (as this is a disjunction).
The last two will be true, if and only if b is true. For the first, this a bit harder to see, but if you look closely: you have now a conjunction (terms concatenated by AND): All of them must be true, for the whole expression to be true, so a and b must be true. Especially b must be true.
In summary: For the whole expression to be true, in all three top-level cases, b must be true (and it will be false, if b is false). So it simplifies to just b.
Explore more on Wolfram Alpha:
https://www.wolframalpha.com/input/?i=a+%26+b+%26+(~b+%7C+c)+%7C+b+%26+c+%7C+b
A.B.(~B+C) + B.C + B = A.B.~B + A.B.C + B.C + B ; Distribution
= A.B.C + B.C + B ; Because B.~B = 0
= B.C + B ; Because A.B.C <= B.C
= B ; Because B.C <= B

How to find the Inverse Kron?

If I know that K = kron ( A , B ),where kron is the Kronecker product of matrices as defined in MATLAB, how can I find A and B from a given matrix K?
for example suppose that
K = [1 0 0 0 ;0 1 0 0 ; 0 1 0 0 ;0 1 0 0 ;1 0 0 0 ;0 1 0 0 ;0 1 0 0 ;0 1 0 0 ;1 0 0 0 ;0 1 0 0 ;0 1 0 0 ;0 1 0 0 ;0 0 1 0 ;0 0 0 1 ;0 0 0 1 ;0 0 0 1 ]
is there any way to find A and B, such that K = kron ( A , B )?
In this case, A and B are as follows:
A = [ 1 0 ; 1 0 ; 1 0 ; 0 1 ]
B = [ 1 0 ; 0 1 ; 0 1 ; 0 1 ]
Short Discussion and Solution Code
You can't find both A and B, given a K, because there could be many possible A's and B's to produce a certain kron matrix, K. Thus, alongwith K, you need either A or B to get the remaining input B or A respectively.
Case #1 Given A and K (kron matrix), you can find B with -
B = K(1:size(K,1)/size(A,1),1:size(K,2)/size(A,2))./A(1)
Case #2 Given B and K (kron matrix), you can find A with -
A = K(1:size(B,1):end,1:size(B,2):end)./B(1)
Thus, if not the entire other input, you would at least need to know the size of it and one of the elements of it, preferably the first element.
Function Code
You can very easily convert that to a function code for an easy plug-n-play usage -
%// INVERSE_KRON Inverse of Kronecker tensor product to find one of the inputs.
% // INVERSE_KRON(K,ARRAY,INPUT_ID) finds one of the inputs used for calculating the
% // Kronecker tensor product given the other input and the ID of that other input.
% // Thus, if K was obtained with K = KRON(A,B), one must use -
% // A = INVERSE_KRON(K,B,2) to find A, and
% // B = INVERSE_KRON(K,A,1) to find B.
function out = inverse_kron(K,array,input_id)
switch input_id
case 1
out = K(1:size(K,1)/size(array,1),1:size(K,2)/size(array,2))./array(1);
case 2
out = K(1:size(array,1):end,1:size(array,2):end)./array(1);
otherwise
error('The Input ID must be either 1 or 2')
end
return;
Typical use case would look like this -
K = kron(A,B); %// Get kron product
A = inverse_kron(K,B,2) %// Recover A
B = inverse_kron(K,A,1) %// Recover B
Note: For a vector case, one other related question and answer could be found here.

How do I 2D-plot my own function with two arguments?

I've started out with MATLAB a few hours ago and began with plotting some simple functions, e.g.:
k = -20:20;
a = 0.01;
x_k = exp(-a * k.^2)
f_1 = figure(1);
plot(k, x_k)
This works fine and plots each value of k on the x-axis, with its corresponding function response at the y-axis. Now I've defined my own function:
function [y] = triangle(t, a)
if (a <= t) & (t <= 0)
y = (1/a * t + 1) * a
elseif (0 <= t) & (t <= a)
y = (-1/a * t + 1) * a
else
error('Function not defined for these values')
end
end
I now want to plot triangle for a range of t with a specific parameter a. So I call:
a = 1;
int = (2 * a) / 20;
t = -a:int:a;
f_1 = figure(1);
plot(t, triangle(t, a))
… but my function errors out because the entire t array (vector, I suppose?) is passed to it instead of each element of t.
How do I plot my triangle function for a specific a, over a defined range?
I've also tried fplot(triangle(a), t) (since fplot accepts a function as an argument) but that again complains about triangle not receiving enough input arguments—rightly so, but I need to pass a to it as well.
The problem of this is the that you pass a vector to your function triangle but you want to check every single if-statement for each single value of the vetor t. So either you use a for-loop within the function triangle or you could also do it by using this:
function [y] = triangle(t, a)
y = ((a <= t) & (t <= 0)) .* ((1/a * t + 1) * a) + ((0 <= t) & (t <= a)) .* ((-1/a * t + 1) * a);
end
I know it looks somehow weird, but if you need me to explain it a bif more in detail, I can do this for you ;-)
EDIT: Let's shortly examine the problem: You pass a vector t to the function, which means that the first if statement if (a <= t) & (t <= 0) splitted looks like this:
(a <= t) % resulting in:
ans =
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
(t <= 0) % resulting in:
ans =
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
so combining them via the AND operator (& for vectors), this obviously gives you
ans =
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
So this branch wont be executed. The elseif gives you:
(0 <= t)
ans =
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
(t <= a)
ans =
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
((0 <= t) & (t <= a))
ans =
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1
so this won't be executed either even though you'd want it to be executed for the second half of your values because you'd like to check the two statements for each value-pair on it's own.
So by leaving away the statements completely you could do it like I posted above: simply multiply the result of the logical statements elementwise with the piecewise function which will yield the result you want to calculate :-)
The best approach is to define the triangle function so that it admits vector inputs. You and do it with logical indexing, which selects a range of values of t depending on a logical condition:
function [y] = triangle(t, a)
y = NaN(size(t)); %// pre-allocate and define NaN as default return value
ind = (a <= t) & (t <= 0); %// select first range
y(ind) = (1/a * t(ind) + 1) * a; %//compute output for first range
ind = (0 <= t) & (t <= a); %// select second range
y(ind) = (-1/a * t(ind) + 1) * a; %//compute output for second range
end
This returns NaN for out-of-range values. As an example, for your t,
>> triangle(t, a)
ans =
Columns 1 through 13
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0000 0.9000 0.8000
Columns 14 through 21
0.7000 0.6000 0.5000 0.4000 0.3000 0.2000 0.1000 0
Once you define the function like this, you can do plot(t, triangle(t, a)).
To pass your function to fplot, you need to use an anonymous function (like what is called a lambda in many other programming languages).
This is done with the # syntax in matlab (see help function_handle for how to use this).
So your fplot try should be:
fplot(#(x) triangle(x,a), t([1 end]))
Note that the t input for fplot is the bounds in which you want to evaluate your function, not the values to evaluate itself (you can use bounds in combination with fplot's third input argument for some control over that).
That said, as other posters also noted, the part of your example input where t<0 end up right in your else branch and yields an error.

Basic identities of logical expressions and deriving logical expressions from truth table?

I was wondering what a basic identity of a logical expression is and how to get it. I looked on google but couldn't find anything about it.
Say, for example I have a logical expression ~(~(P ^ ~(P ^ Q)) ^ ~(Q ^ ~(P ^ Q)))
Below is the result I got from a truth table and I don't know what to do with it to get a basic identity.
0
1
1
0
As well, as that I have a truth table and I have no idea how to derive a logical expression from it.
P Q R F
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1
When you have the truth table, creating a DNF formula is trivial. Take a look at where the assignment is true. Then you end you end up with (exclamation mark means negation)
(P & !Q & R) OR (P & Q & !R) OR (P & Q & R).