What the difference between <= and = in cocotb? - hdl

It seem that I can use indifferently <= or = to set an input signal value on my design.
Is there a real difference between two ?
dut.button_in = 0
or
dut.button_in <= 0
I have exactly the same output chronogram.

The answer can be found here.
There is no fundamental difference between <= and = except that = can ovewrite the reference and <= is only used for value assignement.
AlexanderSpirin give some examples to illustrate the problem :
#cocotb.test()
def parallel_example(dut):
reset_n = dut.reset
dut.reset = 1 # OK
dut.reset <= 1 # OK hdl-like shortcut for the next one
dut.reset.value = 1 # OK
reset_n <= 1 # OK
reset_n.value = 1 # OK
reset_n = 1 # Doesn't work: reference overwrite
Thanks to Vinay Madupura for the clue.

Related

how to convert function output into list, dict or as data frame?

My issue is, i don't know how to use the output of a function properly. The output contains multiple lines (j = column , i = testresult)
I want to use the output for some other rules in other functions. (eg. if (i) testresult > 5 then something)
I have a function with two loops. The function goes threw every column and test something. This works fine.
def test():
scope = range(10)
scope2 = range(len(df1.columns))
for (j) in scope2:
for (i) in scope:
if df1.iloc[:,[j]].shift(i).loc[selected_week].item() > df1.iloc[:,[j]].shift(i+1).loc[selected_week].item():
i + 1
else:
print(j,i)
break
Output:
test()
1 0
2 3
3 3
4 1
5 0
6 6
7 0
8 1
9 0
10 1
11 1
12 0
13 0
14 0
15 0
I tried to convert it to list, dataframe etc. However, i miss something here.
What is the best way for that?
Thank you!
A fix of your code would be:
def test():
out = []
scope = range(10)
scope2 = range(len(df1.columns))
for j in scope2:
for i in scope:
if df1.iloc[:,[j]].shift(i).loc[selected_week].item() <= df1.iloc[:,[j]].shift(i+1).loc[selected_week].item():
out.append([i, j])
return pd.DataFrame(out)
out = test()
But you probably don't want to use loops as it's slow, please clarify what is your input with a minimal reproducible example and what you are trying to achieve (expected output and logic), we can probably make it a vectorized solution.

I am trying to recreate this R logic within a SQL query. Any ideas on how I should go about doing so? Appreciate any assistance at all

This is the R script that I am attempting to recreate using a CASE WHEN statement in SQL:
dat[ ,X_1_7_Spline := pmax(1,pmin(ifelse(is.na(X),1,X),7))]
It seems that this command is telling the parser to return the parallel maxima of a vector containing a conditional statement as long as the value of variable X lies between 1 and the parallel minima of some value and 7 (as long as the value is not null). It then seems to join the new column containing these values back to the original dataset (dat). I am having some troubles representing the "pmax(1,pmin(ifelse(is.na(X),1,X),7))" portion of the code in my SQL query and would appreciate any ideas on how I might be able to do this effectively.
I have something very remedial right now, which I know does not express this above statement properly:
CASE WHEN MAX(IF(ISNOTNULL(X) AND MIN(X)=1 AND MAX(X)=7) then 1 else X end as X_1_7_Spline
Any thoughts/feedback would be greatly appreciated as I am still trying to understand the R script. Thanks in advance for any insight on this issue.
ifelse(is.na(X),1,X) can be translated into SQL's COALESCE(X, 1); and
pmin and pmax logic can be placed in a CASE WHEN (as you've started)
Perhaps this?
CASE WHEN X < 1 THEN 1
WHEN X > 7 THEN 7
ELSE coalesce(X, 1) END as NewX
We don't need to worry about coalesceing the X < 1 or X > 7 because null < 1 does not resolve as true, so it does not accept that case.
Demo in R using sqldf:
library(data.table)
dat <- data.table(X = c(-1,5,9,NA))
dat[, X_1_7_Spline := pmax(1,pmin(ifelse(is.na(X),1,X),7)) ]
sqldf::sqldf("select *, (CASE WHEN X < 1 THEN 1 WHEN X > 7 THEN 7 ELSE coalesce(X,1) END) as NewX from dat")
# X X_1_7_Spline NewX
# 1 -1 1 1
# 2 5 5 5
# 3 9 7 7
# 4 NA 1 1

Trigger Point of Moving average crossover

I am trying to define the trigger point when wt1(Moving average 1) crosses over wt2(moving average 2) and add it to the column ['side'].
So basically add 1 to side at the moment wt1 crosses above wt2.
This is the current code I am using but doesn't seem to be working.
for i in range(len(df)):
if df.wt1.iloc[i] > df.wt2.iloc[i] and df.wt1.iloc[i-1] < df.wt2.iloc[i-1]:
df.side.iloc[1]
If I do the following:
long_signals = (df.wt1 > df.wt2)
df.loc[long_signals, 'side'] = 1
it return the value of 1 the entire time wt1 is above wt2, which is not what i am trying to do.
Expected outcome is when wt1 crosses above wt2 side should be labeled as 1.
Help would be appreciated!
Use shift in your condition:
long_signals = (df.wt1 > df.wt2) & (df.wt1.shift() <= df.wt2.shift())
df.loc[long_signals, 'side'] = 1
df
if you do not like NaNs in 'side', use df.fillna(0) at the end
Your first piece of code also works with the following small modification
for i in range(len(df)):
if df.wt1.iloc[i] > df.wt2.iloc[i] and df.wt1.iloc[i-1] <= df.wt2.iloc[i-1]:
df.loc[i,'side'] = 1

Iterate through vars without a index?

I set some vars like this:
local var1Age = 10
local var2Age = 20
local var3Age = 30
Now I want to iterate them with a loop like this:
for i=1, 3 do
if var..i..Age >= 21 then
print("yep")
end
end
I can't change the vars, or create a table instead. Is it possible somehow with this vars?
Edit:
I could do something like this:
if var1Age >= 21 then
print("yep")
end
if var2Age >= 21 then
print("yep")
end
if var3Age >= 21 then
print("yep")
end
But I have ~50 vars like that. That's why I search a way to do it with a loop.
Edit2:
The vars are set by a class I can't change, so I can't change the way the vars are set.
For example I can't set the vars like this:
local varAge = {}
varAge[1] = 10
varAge[2] = 20
varAge[3] = 30
Edit3:
The class saves the vars in a table like this: http://ideone.com/iO4I8N
You could iterate through all local variables via debug.getlocal and filter variables you're interested in by name. http://www.lua.org/pil/23.1.1.html
Here is example on how to use it.
local var1Age = 10
local var2Age = 20
local var3Age = 30
function local_var_value(n)
local a = 1
while true do
local name, value = debug.getlocal(2, a)
if not name then break end
if name == n then
return value
end
a = a + 1
end
end
for i=1, 3 do
local v = local_var_value("var"..i.."Age")
if v and v >= 21 then
print("yep")
end
end
Are you really sure you want to stretch the language usage this far? The use of debug library should be left for advanced use when you cannot do otherwise.
Maybe your programming problem could be solved in a more elegant way using "regular" Lua facilities. To have a sequence of variables indexed by a number, simply use a table as an array:
local varAge = {}
varAge[1] = 10
varAge[2] = 20
varAge[3] = 30
for i=1,#varAge do
if varAge[i] >= 21 then
print("yep")
end
end
EDIT
If you really need to use debug.getlocal and performance is really an issue, you can avoid the potential O(n2) behavior scanning the locals only once and storing their values in a table:
local var1Age = 10
local var2Age = 20
local var3Age = 30
local function GetLocalVars( level )
local result = {}
for i = 1, math.huge do
local name, value = debug.getlocal( level, i )
if not name then break end
result[ name ] = value
end
return result
end
local local_vars = GetLocalVars( 2 )
for i = 1, 3 do
local name = "var"..i.."Age"
local v = local_vars[ name ]
if v and v >= 21 then
print("yep")
end
end
Based on the sample code you provided from your comment here, You should be able to iterate through your data structure without ever needing to use debug.getlocal.
local vars = varcount(DTClass)
for i = 1, vars do
local vari = "var" .. i
local variAge = DTClass[vari.."Age"]
if variAge and variAge >= 21 then
print(DTClass[vari.."Weight"])
end
end
This should work whether DTClass is a table or a userdata assuming it provides a suitable __index. Of course you need some way to determine total elements in DTClass. Just implement the varcount function to do this.
If DTClass is a table, varcount can be as simple as return #DTClass / var_fields.

How can I optimize this timeline-matching code in Matlab?

I currently have two timelines (timeline1 and timeline2), with matching data (data1 and data2). Timelines almost, but not quite match (about 90% of common values).
I'm trying to find values from data1 and data2 that correspond to identical timestamps (ignoring all other values)
My first trivial implementation is as follows (and is obviously terribly slow, given that my timelines contain thousands of values). Any ideas on how to improve this? I'm sure there is a smart way of doing this while avoiding the for loop, or the find operation...
% We expect the common timeline to contain
% 0 1 4 5 9
timeline1 = [0 1 4 5 7 8 9 10];
timeline2 = [0 1 2 4 5 6 9];
% Some bogus data
data1 = timeline1*10;
data2 = timeline2*20;
reconstructedData1 = data1;
reconstructedData2 = zeros(size(data1));
currentSearchPosition = 1;
for t = 1:length(timeline1)
% We only look beyond the previous matching location, to speed up find
matchingIndex = find(timeline2(currentSearchPosition:end) == timeline1(t), 1);
if isempty(matchingIndex)
reconstructedData1(t) = nan;
reconstructedData2(t) = nan;
else
reconstructedData2(t) = data2(matchingIndex+currentSearchPosition-1);
currentSearchPosition = currentSearchPosition+matchingIndex;
end
end
% Remove values from data1 for which no match was found in data2
reconstructedData1(isnan(reconstructedData1)) = [];
reconstructedData2(isnan(reconstructedData2)) = [];
You can use Matlab's intersect function:
c = intersect(A, B)
Couldn't you just call INTERSECT?
commonTimeline = intersect(timeline1,timeline2);
commonTimeline =
0 1 4 5 9
You need to use the indexes returned from intersect.
[~ ia ib] = intersect(timeline1, timeline2);
recondata1 = data1(ia);
recondata2 = data2(ib);