Verilog Combinational Logic - module

I'm attempting to implement the following logic equation in Verilog:
A1'*B1 + A1'*A0'*B0 + A0'*B1*B0
where A1, A0, B1, B0 are inputs and ' indicates negation. This is my first go at coding in Verilog, and I'd like to see if I'm on the right track. Any help would be much appreciated.
This is what I have worked up:
1 module HW7P1( A1, A0, B1, B0, O )
2 input A1, A0, B1, B0
3 output reg O;
4
5 always #( A1 or A0 or B1 or B0 )
6 begin
7 if( !A1 && B1 ) begin
8 O <= 1;
9 end else if( !A1 && !A0 && B0 ) begin
10 O <= 1;
11 end else if( !A0 && B1 && B0 ) begin
12 O <= 1;
13 end else begin
14 O <= 0;
15 end
16 end
Have I done anything wrong here?

I believe the following continuous assignment is equivalent to your logic equation:
wire O = (!A1&B1) | (!A1&A0!&B0) | (!A0&B1&B0);
You should create a testbench to prove that this is the logic you desire.

Related

Optimization between 2 dependent variables

I couldn't find a solution nowhere, so I'm asking here. Hope someone knows how to guide me thru.
So, I'm not quite sure if this is a optimization problem (if anyone know what kind of problem is this, let me know), but I need to find the quantity of clients that each attendant has to have so that each has the same amount of orders. I don't know if there is a function or a regression that could be made of this.
Column A has the clients name. Column B has the "difficulty" that each client is to assist - that is, "1" is normal difficulty, "2" is double the normal difficulty and so on - meaning that the orders of this clients will be multiplied by his difficulty. Column C has a spec that only attendant Y can assist. Column D has the quantity of orders that each client requested. And finally column E is the account attendant.
CLIENT
ATTENTION
SPEC
ORDERS
ATTENDANT
a1
3
0
6
y
a2
3
0
7
x
a3
1
0
1
y
a4
1
0
9
y
a5
2
0
6
y
a6
1
0
7
y
a7
3
0
2
y
a8
3
0
9
x
a9
3
0
9
y
a10
2
1
8
y
a11
2
0
8
x
a12
2
0
9
y
a13
1
1
2
y
a14
2
0
4
x
a15
3
0
10
y
a16
2
0
9
x
a17
2
0
8
y
a18
1
1
5
y
a19
3
0
8
x
a20
1
1
3
y
a21
2
0
10
x
a22
2
0
6
x
Summary tables:
ATTENDANT
TOTAL ORDERS
x
61
y
84
ATTENDANT
TOTAL CLIENTS
x
8
y
14
ATTENDANT
TOTAL ORDERS
x
61
y
84
y (spec 0)
66
y (spec 1)
18
Here is a linear program that solves this. Fun problem! This uses the pyomo environment and the separately installed glpk solver. Result: It's a tie! X and Y don't need to haggle! ;)
Code:
# client assignment
import csv
from collections import namedtuple
import pyomo.environ as pyo
data_file = 'data.csv'
Record = namedtuple('Record', ['attention', 'spec', 'orders'])
records = {}
with open(data_file, 'r') as src:
src.readline() # burn header row
reader = csv.reader(src, skipinitialspace=True)
for line in reader:
record = Record(int(line[1]), int(line[2]), int(line[3]))
records[line[0]] = record
#print(records)
# set up the ILP
m = pyo.ConcreteModel()
# SETS
m.C = pyo.Set(initialize=records.keys()) # the set of clients
m.A = pyo.Set(initialize=['X', 'Y']) # the set of attendants
# PARAMETERS
m.attention = pyo.Param(m.C, initialize={c: r.attention for (c, r) in records.items()})
m.y_required = pyo.Param(m.C, initialize={c: r.spec for (c, r) in records.items()})
m.orders = pyo.Param(m.C, initialize={c: r.orders for (c, r) in records.items()})
# VARIABLES
m.assign = pyo.Var(m.A, m.C, domain=pyo.Binary) # 1: assign attendant a to client c
m.work_delta = pyo.Var(domain=pyo.NonNegativeReals) # the abs(work difference)
# OBJECTIVE
# minimize the work delta...
m.obj = pyo.Objective(expr=m.work_delta)
# CONSTRAINTS
# each client must be serviced once and only once
def service(m, c):
return sum(m.assign[a, c] for a in m.A) == 1
m.C1 = pyo.Constraint(m.C, rule=service)
# y-specific customers must be serviced by attendant y, and optionally if not reqd.
def y_serves(m, c):
return m.assign['Y', c] >= m.y_required[c]
m.C2 = pyo.Constraint(m.C, rule=y_serves)
# some convenience expressions to capture work...
m.y_work = sum(m.attention[c] * m.orders[c] * m.assign['Y', c] for c in m.C)
m.x_work = sum(m.attention[c] * m.orders[c] * m.assign['X', c] for c in m.C)
# capture the ABS(y_work - x_work) with 2 constraints
m.C3a = pyo.Constraint(expr=m.work_delta >= m.y_work - m.x_work)
m.C3b = pyo.Constraint(expr=m.work_delta >= m.x_work - m.y_work)
# check the model
#m.pprint()
# SOLVE
solver = pyo.SolverFactory('glpk')
res = solver.solve(m)
# ensure the result is optimal
status = res.Solver()['Termination condition'].value
assert(status == 'optimal', f'error occurred, status: {status}. Check model!')
print(res)
print(f'x work: {pyo.value(m.x_work)} units')
print(f'y work: {pyo.value(m.y_work)} units')
# list assignments
for c in m.C:
for a in m.A:
if pyo.value(m.assign[a, c]):
print(f'Assign {a} to customer {c}')
Output:
Problem:
- Name: unknown
Lower bound: 0.0
Upper bound: 0.0
Number of objectives: 1
Number of constraints: 47
Number of variables: 46
Number of nonzeros: 157
Sense: minimize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 53
Number of created subproblems: 53
Error rc: 0
Time: 0.008551836013793945
Solution:
- number of solutions: 0
number of solutions displayed: 0
x work: 158.0 units
y work: 158.0 units
Assign Y to customer a1
Assign Y to customer a2
Assign X to customer a3
Assign Y to customer a4
Assign Y to customer a5
Assign Y to customer a6
Assign Y to customer a7
Assign Y to customer a8
Assign X to customer a9
Assign Y to customer a10
Assign X to customer a11
Assign X to customer a12
Assign Y to customer a13
Assign X to customer a14
Assign X to customer a15
Assign X to customer a16
Assign X to customer a17
Assign Y to customer a18
Assign X to customer a19
Assign Y to customer a20
Assign Y to customer a21
Assign Y to customer a22
[Finished in 588ms]
In Excel Solver
Note: in the solver options, be sure to de-select "ignore integer constraints"
This seems to work OK. The green shaded areas are "locked" to Y and not in the solver's control.
I'm always suspicious of the solver in Excel, so check everything!

SUM based on another column Sign in Oracle

I have two tables
Table A has only last level id(leaf_id) information along with sum_data.
id sum_data
A5 40
B3 -50
C2 90
Table B has hierarchy information of id's and the sign to be considered for the id.
id Z has three children A2 and B2 and C2
id parent id leaf_id level sign
Z NULL A5 1 +
A2 Z A5 2 +
A3 A2 A5 3 -
A4 A3 A5 4 +
A5 A4 A5 5 +
Z NULL B3 1 +
B2 Z B3 2 -
B3 B2 B3 3 +
Z NULL C2 1 +
C2 Z C2 2 +
I need to calculate sum_data of Z based on sign operator and the calculation follows like this:
id parent id leaf_id level sign sum_data
Z NULL A5 1 + -40 --(rolled up sum_data from A2* sign =-40 * +)
A2 Z A5 2 + -40 --(rolled up sum_data from A3* sign =-40 * +)
A3 A2 A5 3 - -40 --(rolled up sum_data from A4* sign = 40 * -)
A4 A3 A5 4 + +40 --(rolled up sum_data from A5)
A5 A4 A5 5 + 40 --got this from Table A
Z NULL B3 1 + 50 --(rolled up sum_data from B2* sign = 50 * +)
B2 Z B3 2 - 50 --(rolled up sum_data from B3* sign = -50 * -)
B3 B2 B3 3 + -50 -- got this from Table A
Z NULL C2 1 + 0
C2 Z C2 2 ignore 0 -- (90 comes from Table A, as sign is ignore it is 0)
My output should be
id sum_data
Z 10 ( -40 from A5 hierarchy + 50 from B3 hierarchy + 0 from C2 hierarchy)
Can you please help me in deriving the sum_data in Oracle SQL code.

Why I do not get the right answer

I think logically the following code is right but I get the wrong answer:
.mod file:
set R := {1,2};
set D1 := {1,2,4,5};
set P1 := {1,2,3,4,5};
var V{D1,R}, binary;
param Ud{D1,R} ;
param U{P1,R} ;
minimize obj{p in D1, r in R}: V[p,r] * (Ud[p,r]+ sum{j in P1: j!=p} U[j,r]);
s.t. a10{ r in R }: sum{p in D1} V[p,r]=2 ;
.dat file:
param Ud: 1 2:=
1 -10 -6
2 -20 -4
4 1 -10
5 -4 -4;
param U: 1 2 :=
1 -8.1 -3
2 -6.8 -8
3 -7.2 1
4 -16 -4
5 -6.8 -4;
Basically for each r and for two p , I want to minimize (Ud[p,r] + sum{j in P: j!=p} U[j,r])
But it always give me V[1,r]=v[5,r]=1 even if V[2,r] minimize obj function.
I except to get V[2,r]=1 because -20 + (-8.1-7.2 -16-6.8) is the most negative.
Your syntax for the objective function is incorrect; it should be
minimize obj: sum {p in D1, r in R} V[p,r] * (Ud[p,r]+ sum{j in P1: j != p} U[j,r]);
(Note the location of the colon (:), and the presence of the sum.) To be honest I'm not exactly sure what AMPL was doing in response to your objective function, but I would just treat the results as unpredictable.
With the revised objective function, the optimal solution is:
ampl: display V;
V :=
1 1 1
1 2 1
2 1 1
2 2 0
4 1 0
4 2 1
5 1 0
5 2 0
;

Generating binary variables in Pig

I am newbie to the world of Pig and I need to implement the following scenario.
problem:
Input to pig script: Any arbitrary relation say as below table
A B C
a1 b1 c1
a2 b2 c2
a1 b1 c3
we have to generate binary columns based on B,C so my output will look something like this.
output
A B C B.b1 B.b2 C.c1 C.c2 C.c3
a1 b1 c1 1 0 1 0 0
a2 b2 c2 0 1 0 1 0
a1 b1 c3 1 0 0 0 1
Can someone let me know how to achieve this in pig? i know this can be easily achieved using R script but my requirement is to achieve via PIG.
Your help will be highly appreciated.
Can you try this?
input
a1 b1 c1
a2 b2 c2
a1 b1 c3
PigScript:
X = LOAD 'input' USING PigStorage() AS (A:chararray,B:chararray,C:chararray);
Y = FOREACH X GENERATE A,B,C,
((B=='b1')?1:0) AS Bb1,
((B=='b2')?1:0) AS Bb2,
((C=='c1')?1:0) AS Cc1,
((C=='c2')?1:0) AS Cc2,
((C=='c3')?1:0) AS Cc3;
DUMP Y;
Output:
(a1,b1,c1,1,0,1,0,0)
(a2,b2,c2,0,1,0,1,0)
(a1,b1,c3,1,0,0,0,1)

Convert a value based on range

I need to convert a number to another value based on a range:
ie:
7 = "A"
106 = "I"
I have a range like this:
from to return-val
1 17 A
17 35 B
35 38 C
38 56 D
56 72 E
72 88 F
88 98 G
98 104 H
104 115 I
115 120 J
120 123 K
123 129 L
129 infinity M
The values are fixed and do not change.
I was thinking a lookup table would be required, but is there a way it could be done with a function on an analytics function inside of oracle?
Think I would use a mapping table:
mapping:
to ret
17 A
38 B
Select Max(ret)
From mapping
Where x <= to
You could also use CASE WHEN:
Select Case When x <= 17 Then 'A'
When x <= 35 Then 'B'
When x <= 38 Then 'C'
...
Else 'M' End
From your_table
SQL servers are designed such that operating on a table is faster than anything else -- particularly when that table will only have 13 rows.
I would create a function, in oracle, since it should be more efficient than doing a table lookup (no roundtrip to disk will ever be involved).
CREATE OR REPLACE Function ValueFromRange
( n IN number )
RETURN varchar2
IS
ret varchar2;
BEGIN
ret := -1; -- UNDEFINED?
IF n >= 1 and n <= 17 THEN
ret := 'A';
ELSIF n >= 18 and n <= 35 THEN
ret := 'B';
ELSIF n >= 36 and n <= 38 THEN
ret := 'C';
ELSIF n >= 39 and n <= 56 THEN
ret := 'D';
ELSIF n >= 57 and n <= 72 THEN
ret := 'E';
ELSIF n >= 73 and n <= 88 THEN
ret := 'F';
ELSIF n >= 89 and n <= 98 THEN
ret := 'G';
ELSIF n >= 99 and n <= 104 THEN
ret := 'H';
ELSIF n >= 105 and n <= 115 THEN
ret := 'I';
ELSIF n >= 116 and n <= 120 THEN
ret := 'J';
ELSIF n >= 121 and n <= 123 THEN
ret := 'K';
ELSIF n >= 124 and n <= 129 THEN
ret := 'L';
ELSIF n >= 130 THEN
ret := 'M';
END IF;
RETURN ret;
END;