Connect internal signal to output port in MyHDL module - myhdl

Considering the following example (a simple 8-bit counter), is there a simpler way to connect the internal s_count signal to the o_count port?
def counter(i_clk, i_reset, o_count):
""" A free-running 8-bit counter with a synchronous reset """
s_count = Signal(intbv(0)[8:])
#always(i_clk.posedge)
def count():
if i_reset == 1:
s_count.next = 0
else:
s_count.next = s_count + 1
#always_comb
def outputs():
o_count.next = s_count
return count, outputs
Of course, I could directly increment o_count in the count function but this translates to an inout port in the generated VHDL module, which I don't want.

I suspect directly incrementing o_count is an acceptable solution.
Indeed, it translates to an inout because you cannot read output ports in VHDL.
However, this will only happen when you convert this module as a top module. It is likely that this is a small submodule however. In that case, the hierarchy is flattened out and o_count will be an internal signal.

Related

How to access a collection of heterogenous functions randomly?

I am implementing an evolutionary algorithm where I have a numerical genetic encoding (0-n). Where each number from 0 to n represents a function. I have implemented a numpy version where it is possible to do the following. The actual implementation is a bit more complicated but this snippet captures the core functionality.
n = 3
max_ops = 10
# Generate randomly generated args and OPs
for i in range(number_of_iterations):
args = np.random.randint(min_val_arg, max_val_arg, size=(arg_count, arg_shape[0], arg_shape[1])
gene_of_operations = np.random.randint(0,n,size=(max_ops))
# A collection of OP encodings and operations. Doesn't need to be a dict.
dict_of_n_OPs = {
0:np.add,
1:np.multiply,
2:np.diff
}
#njit
def execute_genome(gene_of_operations, args, dict_of_n_OPs):
result = 0
for op, arg in zip(gene_of_operations,args)
result+= op(arg)
return result
## executing the gene
execute_genome(gene_of_operations, args, dict_of_n_OPs)
print(results)
Now when adding the njit decorator expects a statically typed function. Where heterogenously typed collections such as my dict_of_n_OPs are not supported, I have tried rendering it as a numpy array, numba.typed.Dict, numba.typed.List. But discovered none supports heteregoenous types.
What would be a numba compliant approach that allows for executing different functions based on a numerical encoding such as '00201'. Where number 0 would execute function 0?
Is the only way an n line if else statement for n unique operations/functions?

Dynamic generation of signal spies in testbench

I have a .txt file that contains certain signals that I want to monitor in my testbench during the application of some stimulus.
I am creating an initial block in which I am reading the file and then I try to generate a init_signal_spy() for every one of the lines that I have read.
The code that I have written up until this point has the following format:
module testbench();
logic probes[];
initial begin : read_signals_to_dump_at
automatic int fd;
automatic string fname,line,line_stripped;
if ($value$plusargs("sigfile=%s",fname)) begin : read
fd = $fopen(fname,"r");
while($fgets(line,fd)) begin
//static logic net_to_be_probed;
automatic sig_and_spy entry = new();
// Trim away the '\n' from the line.
line_stripped = line.substr(0,line.len()-2);
// Resize the array
probes = new [probes.size() + 1] (probes);
// Link the extracted new line with the probe list
// - this raises an error "An invalid empty string was passed in as the Destination object."
// - expected since the last element is empty...
$init_signal_spy(line_stripped, probes[probes.size()-1] , 1);
end
end
end : read_signals_to_dump_at
endmodule
In the code above, just before I issue the generation for the spy, I get why the error
An invalid empty string was passed in as the Destination object.
is generated by the compiler. Although the array has been resized, it does not hold any element i.e., its empty. Thus, I tried creating locally a logic variable that then I assign to the signal spy within the loop in the following manner:
module testbench();
logic probes[];
initial begin : read_signals_to_dump_at
automatic int fd;
automatic string fname,line,line_stripped;
if ($value$plusargs("sigfile=%s",fname)) begin : read
fd = $fopen(fname,"r");
while($fgets(line,fd)) begin
logic new_probe;
// Trim away the '\n' from the line.
line_stripped = line.substr(0,line.len()-2);
// Resize the array and copy old values.
probes = new [probes.size() + 1] (probes);
// Add the new probe to the Testbenchs' probes array
probes[probes.size()-1] = new_probe;
// Again, An invalid empty string was passed in as the Destination object.
$init_signal_spy(line_stripped, probes[probes.size()-1] , 1);
end
end
end : read_signals_to_dump_at
endmodule
But then again, I see the same error at runtime during the simulation. So...Is there a way of achieving such a "dynamic" signal monitoring in the testbench somehow? As far as I understood the error concerns that the destination object is NOT a signal of the testbench. Thus the logic new_probe has no effect. Which is to be expected I mean, but is there a way of achieving the desired behavior in the Testbench via sysverilog?
You have at least two problems.
Both the source and destination arguments to init_signal_spy() need to be strings. Your destination argument is an integral variable with a 0 value, and that gets interpreted as a null string. init_signal_spy() was designed for mixed language simulation, and using strings was the only way to achieve that.
Your destination variable should be queue, not a dynamic array. Every time you re-size a dynamic array, the previous elements get relocated and that breaks the previous connection made by signal spy.
This example shows the proper syntax for string this up
module top;
int A[$];
int s1,s2;
initial begin
A.push_back(0);
$init_signal_spy("s1","A[0]");
A.push_back(0);
$init_signal_spy("s2","A[1]");
#1 s1 = 1;
#1 s2 = 2;
#1 $display("%p",A);
end
endmodule
A far better solution for performance is converting your .txt file into actual SystemVerilog code that can be compiled into your testbench.

error using parallel.p​ool.consta​nt/get value MATLAB (parallel computing toolbox)

so this is my code (not sure about function handle in parfeval). The error I get is on line 11. I dont understand the error
poolobj=parpool('my_cluster',8);
[up, op]=ndgri(1e-3:1e-2:1,1e-3:1e-2:1);
up=reshape(up, [1,size(up,1)*size(up,2)]);
up=reshape(up, [1,size(up,1)*size(up,2)]);
z=rand(5,5e3);
addAttachedFiles('<path to my function/cores_random.m');%%to add the function files to workers on the pool
C1=parallel.pool.Constant(z);%%use parallel.pool.Constant to copy these variables into workers
U2=parallel.pool.Constant(up);
O2=parallel.pool.Constant(op);
for i=1:size(up,2)
f1(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(1,:)); %%line 11
f2(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(2,:));
f3(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(3,:));
f4(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(4,:));
f5(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(5,:));
end
for j=1:size(up,2):-1:1
[idx1,u1,o1,ep1]=fetchNext(f1);
[idx2,u2,o2,ep2]=fetchNext(f2);
[idx3,u3,o3,ep3]=fetchNext(f3);
[idx4,u4,o4,ep4]=fetchNext(f4);
[idx5,u5,o5,ep5]=fetchNext(f5);
end
I got an error
{Error using paralle.pool.Constant/get.Value The value of a parallel.pool.Constant is only available on the workers.
Error in main_parallel_norm (line 11)
f1(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(1,:));
the function cores_random is as the following:
[uu,oo,ep]=cores_random(up,op,z)
%%doing some calculations here
%%z is of size 1*1e3
%%up is scalar op is scalar
end
As the error message states, the Value property of a parallel.pool.Constant is available only on the workers. As written, your parfeval requests are trying to access it on the client. Briefly, your code looks like this:
c = parallel.pool.Constant(42);
f = parfeval(pool, #myFcn, 1, c.Value);
This forces the client to evaluate c.Value when setting up the parfeval call.
What you should do instead is pass the Constant itself into the parfeval request, and then access the Value field on the workers. One way to do that is like this:
c = parallel.pool.Constant(42);
f = parfeval(pool, #(const) myFcn(const.Value), 1, c);
This ensures that the const.Value expression is only evaluated on the workers. (Alternatively, you could modify myFcn to know that it needs to call const.Value on its input arguments.)

Fast iteration over unicode string Cython

I have the following cython function.
01:
+02: cdef int count_char_in_x(unicode x,Py_UCS4 c):
03: cdef:
+04: int count = 0
05: Py_UCS4 x_k
06:
+07: for x_k in x: ## Yellow
+08: if x_k == c:
+09: count+=1
10:
+11: return count
Line 07 is not properly optimized.
The annotated HTML code is expanded as:
+07: for x_k in x: ## Yellow
if (unlikely(__pyx_v_x == Py_None)) {
PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
__PYX_ERR(0, 8, __pyx_L1_error)
}
__Pyx_INCREF(__pyx_v_x);
__pyx_t_1 = __pyx_v_x;
__pyx_t_6 = __Pyx_init_unicode_iteration(__pyx_t_1, (&__pyx_t_3), (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 8, __pyx_L1_error)
for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_3; __pyx_t_7++) {
__pyx_t_2 = __pyx_t_7;
__pyx_v_x_k = __Pyx_PyUnicode_READ(__pyx_t_5, __pyx_t_4, __pyx_t_2);
Any tips on how could this be improved?
I think it is possible to write a cdef/cpdef function that at runtime completly avoids Python None type checks. Any idea on how this could be done?
The generated C code looks pretty good to me. The loop overall is a int-iterated for loop (i.e. it's not relying on calling the Python methods __iter__ and __next__).
__Pyx_PyUnicode_READ is translated pretty directly to PyUnicode_READ (depending slightly on the Python version you're using). PyUnicode_READ is a C macro which is as close to a direct array access as you can get.
This is probably as good as it's getting. You might get a small improvement by using bytes rather than unicode (provided you're dealing with ASCII characters). You might just consider whether it's really worth reimplementing unicode.count.
If it were a regular def function you could declare x as unicode not None to remove the None check before the loop. That might make a small difference. However, as #ead points out that isn't supported for cdef functions. It's likely the cost of a def function call will be slightly larger than the cost of a None-check, but you should time it if you care.

Can pysnmp return octectstring values only

I am doing a small script to get SNMP traps with PySnmp.
I am able to get the oid = value pairs, but the value is too long with a small information in the end. How can I access the octectstring only which comes in the end of the value. Is there a way other than string manipulations? Please comment.
OID =_BindValue(componentType=NamedTypes(NamedType('value', ObjectSyntax------------------------------------------------(DELETED)-----------------(None, OctetString(b'New Alarm'))))
Is it possible to get the output like the following, as is available from another SNMP client:
.iso.org.dod.internet.private.enterprises.xxxx.1.1.2.2.14: CM_DAS Alarm Traps:
Edit - the codes are :
**for oid, val in varBinds:
print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))
target.write(str(val))**
On screen, it shows short, but on file, the val is so long.
Usage of target.write( str(val[0][1][2])) does not work for all (program stops with error), but the 1st oid(time tick) gets it fine.
How can I get the value from tail as the actual value is found there for all oids.
Thanks.
SNMP transfers information in form of a sequence of OID-value pairs called variable-bindings:
variable_bindings = [[oid1, value1], [oid2, value2], ...]
Once you get the variable-bindings sequence from SNMP PDU, to access value1, for example, you might do:
variable_binding1 = variable_bindings[0]
value1 = variable_binding1[1]
To access the tail part of value1 (assuming it's a string) you could simply subscribe it:
tail_of_value1 = value1[-10:]
I guess in your question you operate on a single variable_binding, not a sequence of them.
If you want pysnmp to translate oid-value pair into a human-friendly representation (of MIB object name, MIB object value), you'd have to pass original OID-value pair to the ObjectType class and run it through MIB resolver as explained in the documentation.
Thanks...
the following codes works like somwwhat I was looking for.
if str(oid)=="1.3.6.1.2.1.1.3.0":
target.write(" = str(val[0][1]['timeticks-value']) = " +str(val[0][1]['timeticks-value'])) # time ticks
else:
target.write("= val[0][0]['string-value']= " + str(val[0][0]['string-value']))