In my project I have something like this:
reg [15:0] mem [3:0];
wire [63:0] data;
I know I can concatenate the mem into data like this:
assign data = {mem[3], mem[2], mem[1], mem[0]};
but it becomes some bad work when the memory grows big:
reg [3:0] mem [255:0];
wire [1023:0] data;
I'm afraid writing something like this isn't going to be a good idea, even I can write some other Python or Ruby script to generate such a line.
assign data = {mem[255], ..........., mem[0]};
summon_cthulhu();
Is there any better approach to do this?
Note: This is not an XY problem - it's the exact problem that I want to solve.
Use a generate-for loop
genvar ii;
for (ii=0;ii<256;ii=ii+1)
assign data[ii*16+:16] = mem[ii];
Here is one way to do it.
parameter MEM_WIDTH = 4;
parameter MEM_DEPTH = 256;
localparam DATA_SIZE = (MEM_WIDTH * MEM_DEPTH);
reg[MEM_WIDTH-1:0]mem[MEM_DEPTH-1:0];
reg[DATA_SIZE-1:0]data;
always#(*)
begin
for(i=0; i<MEM_DEPTH; i=i+1)
begin
data[i*MEM_WIDTH +: MEM_WIDTH] = mem[i];
end
end
Related
I have never heard of ThinkOrSwrim till yesterday when someone asked me to convert a ThinkOrSwim script to an MQL4 indicator.
A part of the code is as follows:
input length = 21;
input price = close;
input ATRs=1;
input trueRangeAverageType = AverageType.WILDERS;
def flag;
def EMA = ExpAverage(close, length);
def shift1 = ATRs * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
I want to ask you to kindly check and let me know if my understanding is correct.
input ATRs=1; // This should be a multiplier for ATR, then I think I should give it a double
//type for more flexible control.
input trueRangeAverageType = AverageType.WILDERS;
//As far as I understood, wilders is the same as SMMA in MQL.
.
def shift1 = ATRs * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
Here is the main piece of this code which I need your help with.
My understanding is as follows
ATRs ==>> Just a multiplier
I think the rest of this line is calculating the ATR, right?
If so, then I can see that I cannot simply convert this to iATR (in mql), because we are not able to choose MA Methode of ATR in mql4.
Then I think first I have to put the "True Range" of each bar in an array and then use this array as a price source to get the averages.
MQL4:
for(int i = 0; i < rates_total; i++)
{
data[i] = iATR(_Symbol, TF_1, 1, i);
}
for(int i = 0; i < limit; i++)
{
ExtBuffer[i] = iMAOnArray(data, 0, Inplenght, 0, InpMAMethod, i);
}
If I'm in the right way yet, Then I think the iATR period has to be 1, to have the TrueRange of each bar and not the average of the TrueRanges.
And then have the variable length (from thinkOrSwim inputs) as the period parameter for iMAOnArray.
I would appreciate any help with it.
Regards
Edit:
I forgot to ask you something,
why should the programmer who wrote this thinkscript code call this variable shift1?
I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:
var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76
Is there a way to evaluate the string in this manner?
As far as I'm aware, there isn't a formula solver package developed for Dart yet. (If one exists or gets created after this post, we can edit it into the answer.)
EDIT: Mattia in the comments points out the math_expressions package, which looks pretty robust and easy to use.
There is a way to execute arbitrary Dart code as a string, but it has several problems. A] It's very roundabout and convoluted; B] it becomes a massive security issue; and C] it only works if the Dart is compiled in JIT mode (so in Flutter this means it will only work in debug builds, not release builds).
So the answer is that unfortunately, you will have to implement it yourself. The good news is that, for simple 4-function arithmetic, this is pretty straight-forward, and you can follow a tutorial on writing a calculator app like this one to see how it's done.
Of course, if all your formulas only contain two terms with an operator between them like in your example snippet, it becomes even easier. You can do the whole thing in just a few lines of code:
void main() {
final amount = 100;
final formula = '5/105';
final pattern = RegExp(r'(\d+)([\/+*-])(\d+)');
final match = pattern.firstMatch(formula);
final value = process(num.parse(match[1]), match[2], num.parse(match[3]));
final total = amount * value;
print(total); // Prints: 4.761904761904762
}
num process(num a, String operator, num b) {
switch (operator) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
throw ArgumentError(operator);
}
There are a few packages that can be used to accomplish this:
pub.dev/packages/function_tree
pub.dev/packages/math_expressions
pub.dev/packages/expressions
I used function_tree as follows:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
final tax = amount * formula.interpret();
I haven't tried it, but using math_expressions it should look like this:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
Parser p = Parser();
// Context is used to evaluate variables, can be empty in this case.
ContextModel cm = ContextModel();
Expression exp = p.parse(formula) * p.parse(amount.toString());
// or..
//Expression exp = p.parse(formula) * Number(amount);
double result = exp.evaluate(EvaluationType.REAL, cm);
// Result: 2.394047619047619
print('Result: ${result}');
Thanks to fkleon for the math_expressions help.
Imagine a gfor with a seq j...
If I need to use the value of the instance j as a index, who can I do that?
something like:
vector<double> a(n);
gfor(seq j, n){
//Do some calculation and save this on someValue
a[j] = someValue;
}
Someone can help me (again) ?
Thanks.
I've found a solution for this...
if someone had a better option, feel free to post...
First, create a seq with the same size of your gfor instances.
Then, convert that seq in a array.
Now, take the value of that line on array (it's equals the index)
seq sequencia(0, 200);
af::array sqc = sequencia;
//Inside the gfor loop
countLoop = (int) sqc(j).scalar<float>();
Your approach works, but breaks gfors parallelization as converting the index to a scalar forces it to be written from the gpu back to the host, slamming the breaks on the GPU.
You want to do it more like this :
af::array a(200);
gfor(seq j, 200){
//Do some calculation and save this on someValue
a[j] = af::array(someValue); // for someValue a primitive type, say float
}
// ... Now we're safe outside the parallel loop, let's grab the array results
float results[200];
a.host(results) // Copy array from GPU to host, populating a c-type array
I currently stuck in a problem.
Below is the original code
sem_t s;
sem_init(&s, 0, 1);
And I need to replace sem_init with sem_open because it will be used on iOS
sem_t s;
sem_open("/s", O_CREAT, 0644, 1); //which will return sem_t*
How should I assign the return address to s?
Thanks
p.s. i do not declare sem_t* s, because this is a huge library which I won't change it too much
Create a new semaphore pointer,
sem_t *sptr;
Invoke sem_open as sptr holds the address,
sptr = sem_open("/s", O_CREAT, 0644, 1);
And below preprocessor macro should do the trick,
#define s *sptr
With the above method, when ever s is passed as argument, for example sem_wait(&s) boils to sem_wait(&*sptr) => sem_wait(sptr) which is desired without changing sem_t s.
Ok so this is my scenario:
rascal>map[int, list[int]] g = ();
rascal>g += (1:[2]);
This will result in:
rascal>g[1];
list[int]: [2]
So far so good, but now I wanted to do this, but it didn't work:
rascal>g[1] += 3;
|stdin:///|(2,1,<1,2>,<1,3>): insert into collection not supported on value and int
So I can't directly use the value from g[1] and will have to use a temporary variable like this:
rascal>lst = g[1];
rascal>lst += 3;
rascal>g[1] = lst;
map[int, list[int]]: (1:[2,3])
But doing this everytime I want to extent my list is a drag!
Am I doing something wrong or would this be an awesome feature?
Richard
Good question! + on lists is concatenation not insert, so you could type the following to get the desired effect:
g[1] += [2];