Why can't I import a let definition from a package, in a SystemVerilog module? - system-verilog

I would like to put the following definitions in a default package, which I include in all my other SystemVerilog modules:
let max(a,b) = a > b ? a : b;
But, when I try to use the imported let definition in a module, I'm told that I'm attempting to use a non-local function definition and VCS errors out.
Why?

The simple example works with no issues. Make sure that the package is always compiled before it is imported. Do correct import from the package either as pkg::* or pkg::max. Or use it as pkg::max(a,b) directly without import. And yes, use the compiler which supports this syntax.
package pkg;
let max(a,b) = a > b ? a : b;
endpackage:pkg
module top();
import pkg::*;
int a = 1,b = 2;
initial begin
$display("max of %d and %d is %d", a, b, max(a,b));
end
endmodule

Related

Imported function lacks method defined in another module

I have a module A that describes a framework. Then, a couple of modules (here just B) that implement the framework. Finally, I want C to use any of the implementations.
However, running the following example:
module A
abstract type Ab end
f(::Ab) = "Not NotImplemented"
export Ab, f
end
module B
using Main.A
struct Bb <: A.Ab end
A.f(::Bb) = "B"
export Bb, f
end
module C
using Main.A
struct Cc
btype :: A.Ab
end
f(model::Cc) = f(model.btype)
function g(model::Cc)
#show f(model)
end
export Cc, g
end
using Main.A, Main.B, Main.C
ex0 = B.Bb()
ex1 = C.Cc(ex0)
g(ex1)
returns an error
ERROR: LoadError: MethodError: no method matching f(::Main.B.Bb)
Closest candidates are:
f(::Main.C.Cc) at C:\Users\tangi\.julia\dev\VariationalInequalitySolver\script.jl:2
and I really don't want to have to import B in the module C to guarantee genericity.
The problem is:
f(model::Cc) = f(model.btype)
in your C module as it creates a new function in module C that has name f.
You need to write:
A.f(model::Cc) = f(model.btype)
which creates a new method for function f from module A.

How to redeclare package in a model before making an instance?

I would like to do
M_type(redeclare package L=L2) m2_instance;
but does not work. Instead I can write
model M2_type
extends M_type(redeclare package L=L2);
end M2_type;
M2_type m2_instance;
Is here not a shorter way to do this and avoid declaring M2_type?
The redeclare modifier must be moved to the instance name.
M_type(redeclare package L=L2) m2_instance; // wrong syntax
M_type m2_instance(redeclare package L=L2); // correct
Below is a small package, which demonstrates everything and simulates perfectly fine in Dymola 2021x and OpenModelica 1.16.2.
package Redeclaration
package L1
constant Real x = 1;
end L1;
package L2
constant Real x = 2;
end L2;
model M_type
replaceable package L = L1;
Real x = L.x;
end M_type;
model Example
M_type m_instance(redeclare package L=L2);
end Example;
end Redeclaration;

Can multiple modules have the same module type? How do I organize them and their interface files?

Currently, I have within the same OCaml file,
blah.ml:
module type blah =
sig
val a : some-type
end
module type X =
sig
val x : some-type
end
module Y : X =
struct
let x = some-def
end
module Z : X =
struct
let x = some-other-def
end
blah.mli looks like this:
module type blah =
sig
val a
end
module type X =
sig
val x : some-type
end
module Y : X
module Z : X
I want X, Y, and Z to be in separate files with separate interfaces. How do I tell in Y.mli and Z.mli that Y and Z have type X?
Any readings for this would also be appreciated. There are a lot of resources talking about modules, interfaces, and functors, but they don't mention interface files for modules that have other modules as types.
You can create x.ml containing the sig, y.ml containing the module, and z.ml containing that module. You don't need to do anything special to tell the compiler that Y : X and Z : X. The compiler infers the module type automatically from the fact that the module conforms to the type i.e. it implements every binding that the module type needs. If Y or Z don't conform, the type error will be shown at the point of use.
If you want to restrict the module type at the point of definition that's also doable, by giving each module an interface file and includeing the required signature there. For example:
(* x.ml *)
module type S = sig
val x : some-type
end
(* y.mli *)
include X.S
(* y.ml *)
let x = some-def
...and so on.
However this often becomes too restrictive as the signature hides too much detail about the types. So in reality you may actually need to add type equality sharing constraints to avoid compile errors where you want to expose more type info. E.g.:
(* y.mli *)
include X.S with type t = int
Often it is easier to not have the explicit interface file at all unless you really need to make some parts of the module private.

import user defined modules into pydev

I am a beginner to Eclipse neon + Pydev combo.
Trying to use python modules I created into other modules I will be creating.
For a start, I was going to use TKinter tutorial program outlined here:
http://effbot.org/tkinterbook/tkinter-hello-again.htm
In addition to printing a statement in response to a mouse click, I want to run a small module, fibo.py
Here's my code:
import the library
from tkinter import *
import fibo
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(
frame, text="QUIT", fg="red", command=frame.quit
)
self.button.pack(side=LEFT)
self.hi_there = Button(frame, text="Hello",command=self.say_hi)
self.hi_there.pack(side=LEFT)
def say_hi(self):
fib(100)
print ("hi there, everyone!")
root = Tk()
app = App(root)
root.mainloop()
root.destroy() # optional; see description below
Here's fibo.py
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print (b, end=" ")
a, b = b, a+b
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
Both modules are in the same project and workspace.
The editor says,"unresolved import fibo"
Why is the module fibo not recognized by in pydev/eclipse?
My ultimate goal is to run a module upon button click. If there's a more direct way to accomplish this, I would like to know.
Ok, so, based on your screenshot, the structure you have is actually:
/project (this is the PYTHONPATH root and marked as source folder)
/project/root
/project/root/__init__.py
/project/root/nested
/project/root/nested/__init__.py
/project/root/nested/example.py
/project/root/nested/fibo.py
In this case, your import should be: from root.nested import fibo. Your code may work in the command line, but that's because you added an entry to sys.path only in runtime (so, PyDev can't follow that).
The other option would be moving both example.py and fibo.py to /project.
You can also use a relative import as from . import fibo, but then, to run the module as a __main__ module, you'll have to run modules by the module name (with the -m flag) -- you can configure PyDev to do that at the preferences > PyDev > Run > Launch modules with "python -m mod.name".
As a note, if you just write:
fibo in your case, and wait for the undefined variable error to be shown, you can use Ctrl+1 in that same line to get a suggestion which will write the import for you (or you can do a code-completion which will also write an import for you automatically).

Using a Class/record in an other class (subtype mark required in this context)

I want to learn ADA and have a problem with the 'class'
I have 2 classes A and B and want that class A can use class B.
Class A
with B;
package A is
type A is tagged
record
varA : INTEGER := 0;
varB : INTEGER := 0;
end record;
procedure DOSMTH(A_In : in out A; B_IN: in out B);
end A;
and Class B
package B is
type B is tagged
record
var1 : INTEGER;
var2 : INTEGER;
end record;
procedure DoSMTH2(B_IN: in out B; var : INTEGER);
end B;
If I want to compile A I get following error message:
subtype mark required in this context
found 'B' declared at b.ads:1
Another problem is my 'Main' File which can't use A and B (declaration)
with Ada.Text_IO, A, B;
procedure Main is
a : A;
b : B;
begin
null;
end Main;
I get following Errors:
object "A" cannot be used before end of its declaration
object "B" cannot be used before end of its declaration
I can't find any solution for that. I have read the ADA 2005 Reference Manual but can't find anything.
OK thx for the help,
finaly it works now.
Solution:
Modify Class A to
with B;
package A is
type A is tagged
record
-- u can use a object VAR with
-- objB : B.B
varA : INTEGER := 0;
varB : INTEGER := 0;
end record;
procedure DOSMTH(A_In : in out A; B_IN: in out B.B);
end A
Modify Main to:
with Ada.Text_IO, A, B;
procedure Main is
myA : A.A; --the old one was stupid ...
myB : B.B; --same here
begin
null;
end Main;
The problem with the main program is that Ada isn’t case-sensitive, so when you say
a : A.A;
the compiler sees as far as a : A and thinks that the second A is the same thing as the first, hence the complaint that object "A" cannot be used before end of its declaration.
You can tell the compiler where to look for the package A by qualifying it. Package A is declared at library level, and there’s a notional package Standard you can use to indicate this:
a : Standard.A.A;
However, it’s much better, if you can, to avoid using the same name for different things in the first place.
You only withed package B in package A - in order to use anything form it you have to use qualified name (that is: for record B you should use B.B). Like:
with B;
package A is
type A is tagged
record
varA : INTEGER := 0;
varB : INTEGER := 0;
end record;
procedure DOSMTH(A_In : in out A; B_IN: in out B.B);
end A;
If you want to use things declared in package B without fully qualifying name you should put use B; right after withing it.
As to whether one should use or only with package is hard question - most of the time most Ada programmers that I know (including myself) prefer to with packages only, rarely using them - for example when working with Lumen library (OpenGL binding with glut-like functionality) I usually use Lumen because then I can type GL.Whatever_GL_Function instead of Lumen.GL.Whatever_GL_Function (but I do not "use" Lumen.GL). If package name is long I prefer to rename it inside procedure and in case of types (for operators if defined) one can use type B.B;
PS: I can elaborate more if some parts of it are unclear.
My guess would be that the compiler sees "B" as the name of the package and not the record. Try naming your package or records differently.
Also, if you want to learn Ada, the reference manual is the last place you want to start at. Get the book by Barnes or get one of the older books used at Amazon. You get good books about Ada 95 for 5$ in the used section.