Harris HDL example 4.13 - boolean

I read a book called "Digital design and computers architecture" written by Harris and I have a question about example 4.13 (logic gates with delays).
In that example we build a model for the expression Y = !A*!B*!C + A*!B*!C + A*!B*C. And also, we add a few delays to it: 1ns for inverters, three-input AND gates have a delay of 2ns, three-input OR gates have a delay of 4 ns.
Now, the .sv-code below:
*timescale 1ns/1ps
module example(input a,b,c
output y);
logic ab,bb,cb,n1,n2,n3;
assign #1 {ab,bb,cb} = ~{a,b,c};
assign #2 n1 = ab & bb & cb;
assign #2 n2 = a & bb & cb;
assign #2 n3 = a & bb & c;
assign #4 y = n1 | n2 | n3;
endmodule
So, the question is: what is the logic of such form of programming 3 operands (!A*!B*!C , A*!B*!C , A*!B*C). I don't understand what's happening on the lines from 4 to 8.
Can anyone explain please? Why there are such operands like ab, bb and cb?

ab, bb, and cb are all the logical inverses of a, b, and c (ie, !A, !B, and !C from your logical expression). The "b" or "_B" suffix is often used to indicate the inverse or inverse assertion level.
The assign expression each represent an operation from the original boolean equation:
assign #1 {ab,bb,cb} = ~{a,b,c};
This expression can be thought of as 3 NOT gates with inputs a, b, and c, with outputs ab, bb, and cb respectively. It uses the Verilog bitwise inverse operator ~ as well as the Verilog concatenation operator {} to do the inverse all in one line rather than 3 separate assign expressions.
From there, the assignments of n1, n2, and n3 all correspond to the 3, 3-way and operations in the equation and simply serve as intermediate values in the expression. n1 gets assigned !A * !B * !C, n2 gets A * !B * !C and n3 gets A * !B * C. Notice that each of these has the delay #n for the given gate, with the inverses gets #1; n1, n2 and n3 getting #2 and finally the output y being assigned with the #4 delay as its the final 3-way OR of the ANDed values n1, n2, n3.

Related

Why isn't MATLAB's filter function commutative?

I'm trying to use MATLAB's filter function and noticed that switching b and x (with a = 1) give me different results.
I'm confused as to why this is happening. The filter can be represented as a convolution, and convolution is commutative so assuming a is 1, I would expect the same output if b and x are switched. In other words, using an input signal X with filter B should produce the same output as using an input signal B with a filter X since X * B = B * X where the star denotes convolution.
filter does not apply a convolution with kernel B. Input parameter b defines the coefficients of the polynomial that describes the filter.
You are looking for the function conv.
--
EDIT:
My bad, you are right, switching b and x should give the same results. And for me it does:
>> x=rand(1,10);
>> y=rand(1,10);
>> filter(b,1,x)
ans =
0.1713 0.6816 0.9775 1.4413 1.1430 1.2836 1.5635 1.8397 2.3768 1.7775
>> filter(x,1,b)
ans =
0.1713 0.6816 0.9775 1.4413 1.1430 1.2836 1.5635 1.8397 2.3768 1.7775
filter always returns a result of length of x, so if b is shorter than x, and you switch them, you'll get a shorter result back.

MATLAB Simple Calculation

I am working on MATLAB on my own, and was doing problem 9 on Project Euler
It states
" A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a2 + b2 = c2
For example, 32 + 42 = 9 + 16 = 25 = 52.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc."
Below is the code I wrote; however, it compiles, but does not produce and output. I was hoping to get some feedback on what's wrong, so I can fix it.
Thanks,
syms a;
syms b;
syms c;
d= 1000;
d= a + b + c ;
ab= a.^2 + b.^2;
ab= c.^2;
c
I propose a vectorized way (that is, without using loops) to solve the problem. It may seem relatively complicated, especially if you come from other programming languages; but for Matlab you should get used to this way of approaching problems.
Ingredients:
Vectorization;
Indexing;
Transpose;
Implicit singleton expansion;
hypot;
find.
Read up on these concepts if you are not familiar with them, and then try to solve the problem yourself (which of course is the whole point of Project Euler). As a hint, the code below proceeds along these lines:
Generate a 1×1000 vector containing all possible values for a and b.
Compute a 1000×1000 matrix with the values of c corresponding to each pair a, b
From that compute a new matrix such that each entry contains a+b+c
Find the row and column indices where that matrix equals 1000. Those indices are the desired a and b (why?).
You'll get more than one solution (why?). Pick one.
Compute the product of the obtained a and b and the corresponding c.
Once you have tried yourself, you may want to check the code (move the mouse over it):
ab = 1:1000; % step 1
cc = hypot(ab,ab.'); % step 2
sum_abc = ab+ab.'+cc; % step 3
[a, b] = find(sum_abc==1000); % step 4
a = a(1); b = b(1); % step 5
prod_abc = a*b*cc(a,b); % step 6

Non Commutative Multiplication

I'm trying to implement the axioms for geometric products of two vectors in n-dimensioned Euclidean vector space.
i.e Allowing the user to input the number of dimensions, for e.g 3
Generate e1,e2,e3 as symbols
Allow the user to input two vectors as functions of n-sized vectors eg a=a1e1+a2e2+a3e3; b=b1e1+b2e2+b3e3
where a1,a2... and b1,b2... are scalars
Expand the two vectors a and b
(a1e1+a2e2+a3e3)(b1e1+b2e2+b3e3)
It all works fine for me until this point.
From this point, I require the expansion operation to be non commutative, i.e e2e1=/=e1e2
Is there a way I can do this.
Following that, if the reader is feeling kind, is there a way to implement geometric algebra axioms such as e1e1=e2e2=enen=1
and e2e1=-e1e2
-> eiej=-ejei
Thanks a lot!
What you'd like is a "multiplication" that enumerates all the pairs (T1, T2) where T1 is a term from the first expression, and T2 is a term from the second term.
function C = pairwise_mul(S1, S2)
% ' S1, S2 are cell arrays '
N1 = numel(S1);
N2 = numel(S2);
C = cell(1, N1*N2);
for k1 = 1:N1
for k2 = 1:N2
k = k2 + N1*(k1-1);
C{k} = [S1{k1} S2{k2}];
end;
end;
end
You can invoke it like this:
expr1 = {'a1', 'b1', 'c1'};
expr2 = {'a2', 'b2' };
result = pairwise_mul(expr1, expr2);

Polynomial expansion: Separating polynomial coefficients and x's

I want to automatically calculate expansions of polynomials where there are variables (x1,x2,...) as well as coefficients (c1,c2, ...). My goal is to calculate p(1)*(c1*x1+c2*x2+...)^n+ ... + p(n)*(c1*x1+c2*x2+...)^n .
As you can notice the resulting expression can be written as F(x1,x2...)*g(c1,c2,...) [where F is a row matrix and g is column matrix], i.e. there is some multiplicative decoupling between the coefficients and the variables.
Right now I use the MATLAB symbolic toolbox and construct F and g by manually examining the resulting symbolic expansions. This is not very feasible as if n is big and c=(c1,c2,...) is too big there are too many terms and it is no longer possible manually. For instance for (c1*x1+c2*x2+c3) and n=2, what I want is following.
>> p=[2 5]
p =
2 5
>> syms c1 c2 c3
>> syms x1 x2
>> expression= p(1)*(c1*x1+c2*x2+c3)^2 + p(2)*(c1*x1+c2*x2+c3);
>> expand(expression)
ans =
2*c1^2*x1^2 + 4*c1*c2*x1*x2 + 4*c1*c3*x1 + 5*c1*x1 + 2*c2^2*x2^2 + 4*c2*c3*x2 + 5*c2*x2 + 2*c3^2 + 5*c3
>> F=[5*x1 5*x2 5 4*x1*x2 4*x1 4*x2 2*x1^2 2*x2^2 2]
F =
[ 5*x1, 5*x2, 5, 4*x1*x2, 4*x1, 4*x2, 2*x1^2, 2*x2^2, 2]
>> g=[c1 c2 c3 c1*c2 c1*c3 c2*c3 c1^2 c2^2 c3^2].'
g =
c1
c2
c3
c1*c2
c1*c3
c2*c3
c1^2
c2^2
c3^2
>> expand(F*g)
ans =
2*c1^2*x1^2 + 4*c1*c2*x1*x2 + 4*c1*c3*x1 + 5*c1*x1 + 2*c2^2*x2^2 + 4*c2*c3*x2 + 5*c2*x2 + 2*c3^2 + 5*c3
I have found the following question and it looks like there may be a way to do it automatically using conv etc. If one can come up with an automated solution (or at least some idea towards such automation) for the case where x=(x1,x2) and c=(c1,c2,c3) and n=2, the case depicted above; I guess I may be able to generalize it to higher dimensional cases.
Note: the ordering of terms in F or g does not matter, given that they are ordered in some structured way.
The coefficients from different terms don't overlap. The first term, p(1)*(c'*x)^1, has only terms of degree 1 in xi and ci, and so on. So it becomes a matter of computing the coefficients of one term at a time.
That, too, has a "simple" expression:
p(k)*(c'*x)^k = sum(i1,..,im>=0 with sum(i_)=k)
M(k;i1,..,im)*x1^i1*...*xm^im * c1^i1*...*cm^im
where the summation is such that the sum of all i equals k, and M is the multinomial coefficient.
For m=3, n=2, the i's would be in the order of your example: 110,101,011,200,020,002. M(2;110)=2 so the first term is `p(2)*M(2;110)*x1*x2 = 4*x1*x2'.
Your F and g terms are:
F(...) = p(k)*M(k;i1,..,im)*x1^i1*...*xm^im
g(...) = c1^i1*...*cm^im

Get values for 2 arguments from 1 equation

I have this equation: p = (1 + (q-1)*B*T) ^ (-1/q-1)
The values p, T are known and the diagram p - T makes curbe. I want to calculate q and B so that curbe be as close to straight line is posible.
Some values are:
T p
1 0,999147061
2 0,997121331
3 0,994562513
Is there any way to make matlab (or sth else) to give me the values of B and q ?