Default type input and output signals SystemVerilog - system-verilog

I'm trying to learn by myself SystemVerilog (I'm a university student and in my projects I've always used VHDL) and I have a question concerning data types. So far, I think I understood the differences, pro and cons between reg, wire and logic but I'm wondering, in this code snippet:
module example(
input clk,
input nrst,
input nset,
input up,
input [3:0] preload,
output [3:0] counter
);
what's the default type assigned to inputs and outputs? Is it logic (as it is the best choice for "everyday" circuitry)?

In SystemVerilog, wire and reg/logic are closely related, but independent concepts. logic is a datatype, and wire denotes a net (or network) signal kind. There are two basic signal kinds: nets(wire) and variables(var) In a port list declaration, the default is wire logic, meaning a 1-bit 4-state net.
The defaults start to get more involved when you specify a datatype without a kind and the other way around. For inputs, the default unspecified kind is always a net, but for outputs, as soon as you specify a datatype, the default kind becomes var. Verilog appeals to lazy engineers who do not like coding. I suggest being explicit and never reyling on defaults.
I have some examples of this posted here.

Related

How to pass multiple variables from one model to another model (inner/outer)

Let's say we have the following model:
Collector:
model Collector
Real collect_here;
annotation(defaultComponentPrefixes="inner");
end Collector;
and the following model potentially multiple times:
model Calculator
outer Collector collector;
Real calculatedVariable = 2*time;
equation
calculatedVariable = collector.collect_here;
end Calculator;
The code above works if calcModel is present only once in the system to be simulated. If the model exists more than once I get a singular system. This is demonstrated by the Example below. Changing the parameter works either gives a working or failing system.
model Example
parameter Boolean works = true;
inner Collector collector;
Calculator calculator1;
Calculator calculator2 if not works;
end Example;
Using an array inside the collector to pass multiple variables in it doesn't solve it.
Another possible way to solve this is possible by use of connectors, but I only made it work with one calcModel.
Using multiple instances of Calculator does brake the model, as the single variable calculatedVariable will have multiple equations trying to compute its value. Therefore Dymola complains that the system is structurally singular, in this case meaning that there are more equations than variables in the resulting system of equations.
To give a bit more of an insight: Actually checking Collector will fail, as since Modelica 3.0 every component has to be balanced (meaning it has to have as many unknowns as states), which is not the case for Collector as it does have one unknown but no equation. This strongly limits the possible applications for the inner/outer construct as basically every variable has to be computed where it is defined.
In the given example this is compensated in the overall system if exactly one Calculator is used. So this single combination will work. Although this works, it is something that should not be done - for the obvious reason of being very error-prone (and all sub-models should pass the check).
Your question on how to solve this issue actually misses a description of what the issue actually is. There are some cases in my mind that your approach could be useful for:
You want to plot multiple variables from a single point, which would be collector. For this purpose "variable selections" should be the most straight-forward way to go: see Dymola Manual Vol. 1, Section "4.3.11 Matching and variable selections" on how to apply them.
You want to carry out some mathematical operation on that variables. Then it could be useful to have a vectorized input of variable size. This enables an arbitrary number of connections to this input. For an example of this take a look at: Modelica.Blocks.Math.MultiSum
You want to route multiple signals between different models (which is unlikely judging from your description, but still): Then expandable connectors would be a good possibility. To get an impression of what that does take a look at Modelica.Blocks.Examples.BusUsage.
Hope this helps, otherwise please specify more clearly what you actually want to achieve with your code.
I prepared a demonstrative library for such scenario some days ago. You can access it at https://gist.github.com/beutlich/e630b2bf6cdf3efe96e5e9a637124fe1. If you read the documentation on Example2 you can see the link to an article from H. Elmqvis et. al., which is the clue to your problem. That is, you need a connector, and inherited connects from every Calculator to the one Collector.

What is the occasion when we have to use the 'net' data type in systemverilog?

As I know, nowadays the 'reg' type in systemverilog can used in assign statement.
In old fashion, the assign statement does use the only the 'net' type.
So I want to know that what kind of the signals are should have to be the 'net' type in systemverilog?
Update1
From here, http://www.testbench.in/IF_01_INTERFACE.html
I can find a interface declaration.
interface intf #(parameter BW = 8)(input clk); 
logic read, enable; 
logic [BW -1 :0] addr,data; 
endinterface :intf 
At this here, I want to know that why the read and enable and addr and data signal are clared logic data type? Is there any reason? Why not used reg or wire?
A net is used when there are multiple drivers on a signal, usually in conjunction with a bi-directional port, and for designs at the switch level that require strength to operate. See http://go.mentor.com/wire-vs-reg for more details.
Regarding the usage of net Dave's answer pretty much covers it.
From the IEEE Std 1800-2012,
The keyword reg does not always accurately describe user intent, as it
could be perceived to imply a hardware register. The keyword logic is
a more descriptive term. logic and reg denote the same type.
More info on the usage of logic can be found in below links.
1) Morgans answer
2) Greg's answer

SystemVerilog generic multiplexer

I am trying to come up with a way to define a synthesizable generic multiplexer (either as a function or module) that can be used with wires, and typedefs (enums, structs) in SystemVerilog
Is that possible in any way?
If not, what would be the cleanest approach to write such a multiplexer?
Currently, I am using a multiplexer that takes a two-dimensional array of wires as input and selects one of the elements based on a select signal.
This makes it rather painful as I am stuck casting my typed variables back and forth every time I need to connect them to the multiplexer module.
And sadly, this is made even worse by the fact that a for loop is needed to assign a array of typed elements into an array of wires.
Thanks,
Sébastien.
Well, looks like I'll be able to help myself today.
SystemVerilog allows parameterization of modules with types using the "parameter type" feature. This does exactly what I'm looking for, and seems to be supported by the common vendors.
module mux #(
parameter type T = logic,
parameter SIZE = 2)
(
input wire [SIZE-1:0] select,
input wire T in [SIZE-1:0],
output wire T out
);
Then, the back & forth type casting and actual muxing can be performed within the module, which cleans up the rest of the code.

In SystemVerilog, is it allowed to read a parameter from an interface

I am a bit confused as to if it is legal, from a standards stand point, to read a parameter from an interface.
Like so
interface foo_if #(parameter BAR=5)();
...
logic [BAR-1:0] data;
modport slave(input data, ...);
endinterface
module foobar(foo_if.slave s);
...
logic [s.BAR-1:0] bar;
logic [$bits(s.data)-1:0] m_data;
...
endmodule
I have a problem where a major synthesis tool vendor can not even handle this. And they explicitly tell you in the help message that it is not allowed to use $bits() with a interface member.
However a simulation tool from another vendor handles this perfectly as does another synthesis tool I have.
However in SystemVerilog for Design by S. Sutherland et al. it is stated:
Because the design hierarchy may not be yet fully resolved during
elaboration, it is illegal to assign a parameter, specparam, or
localparam constants a value that is derived from elsewhere in the
design hierarchy
However if I am not allowed to use parameters from interfaces, it really cripples the usefulness of interfaces.
The SystemVerilog 1800-2012 Standard on the other hand states:
25.10 Access to interface objects
Access to objects declared in an interface shall be available by
hierarchical name reference, regardless of whether the interface is
also accessed through a port connection or through a virtual
interface, and regardless of the existence of any declared modports in
that interface. A modport may be used to restrict access to objects
declared in an interface that are referenced through a port connection
or virtual interface by explicitly listing the accessible objects in
the modport. However, objects that are not permissible to be listed in
a modport shall remain accessible.
The issue here is not about access, but what is allowed in places that require constant expressions. The LRM is not very clear that interface port references are not considered hierarchical references. But the tool is not complaining about s.BAR, it is complaining about s.data, which is a variable, not a parameter. Normally, you can't use variables in constant expressions, but the LRM 20.6.2 says
The $bits function can be used as an elaboration time constant when
used on fixed-size data types; hence, it can be used in the
declaration of other data types, variables, or nets.
So $bits(s.data) should have been treated like a parameter expression.
BTW, you should be using the latest freely available IEEE 1800-2012 LRM.

How to write a X86_64 _assembler_?

Goal: I want to write an X86_64 assembler. Note: marked as community wiki
Background: I'm familiar with C. I've written MIPS assembly before. I've written some x86 assembly. However, I want to write an x86_64 assembler -- it should output machine code that I can jump to and start executing (like in a JIT).
Question is: what is the best way to approach this? I realize this problem looks kind large to tackle. I want to start out with a basic minimum set:
Load into register
Arithmetric ops on registers (just integers is fine, no need to mess with FPU yet)
Conditionals
Jumps
Just a basic set to make it Turing complete. Anyone done this? Suggestions / resources?
An assembler, like any other "compiler", is best written as a lexical analyser feeding into a language grammar processor.
Assembly language is usually easier than the regular compiled languages since you don't need to worry about constructs crossing line boundaries and the format is usually fixed.
I wrote an assembler for a (fictional) CPU some two years ago for educational purposes and it basically treated each line as:
optional label (e.g., :loop).
operation (e.g., mov).
operands (e.g., ax,$1).
The easiest way to do it is to ensure that tokens are easily distinguishable.
That's why I made the rule that labels had to begin with : - it made the analysis of the line so much easier. The process for handling a line was:
strip off comments (first ; outside a string to end of line).
extract label if present.
first word is then the operation.
rest are the operands.
You can easily insist that different operands have special markers as well, to make your life easier. All this is assuming you have control over the input format. If you're required to use Intel or AT&T format, it's a little more difficult.
The way I approached it is that there was a simple per-operation function that got called (e.g., doJmp, doCall, doRet) and that function decided on what was allowed in the operands.
For example, doCall only allows a numeric or label, doRet allows nothing.
For example, here's a code segment from the encInstr function:
private static MultiRet encInstr(
boolean ignoreVars,
String opcode,
String operands)
{
if (opcode.length() == 0) return hlprNone(ignoreVars);
if (opcode.equals("defb")) return hlprByte(ignoreVars,operands);
if (opcode.equals("defbr")) return hlprByteR(ignoreVars,operands);
if (opcode.equals("defs")) return hlprString(ignoreVars,operands);
if (opcode.equals("defw")) return hlprWord(ignoreVars,operands);
if (opcode.equals("defwr")) return hlprWordR(ignoreVars,operands);
if (opcode.equals("equ")) return hlprNone(ignoreVars);
if (opcode.equals("org")) return hlprNone(ignoreVars);
if (opcode.equals("adc")) return hlprTwoReg(ignoreVars,0x0a,operands);
if (opcode.equals("add")) return hlprTwoReg(ignoreVars,0x09,operands);
if (opcode.equals("and")) return hlprTwoReg(ignoreVars,0x0d,operands);
The hlpr... functions simply took the operands and returned a byte array containing the instructions. They're useful when many operations have similar operand requirements, such as adc,addandand` all requiring two register operands in the above case (the second parameter controlled what opcode was returned for the instruction).
By making the types of operands easily distinguishable, you can check what operands are provided, whether they are legal and which byte sequences to generate. The separation of operations into their own functions provides for a nice logical structure.
In addition, most CPUs follow a reasonably logical translation from opcode to operation (to make the chip designers lives easier) so there will be very similar calculations on all opcodes that allow, for example, indexed addressing.
In order to properly create code in a CPU that allows variable-length instructions, you're best of doing it in two passes.
In the first pass, don't generate code, just generate the lengths of instructions. This allows you to assign values to all labels as you encounter them. The second pass will generate the code and can fill in references to those labels since their values are known. The ignoreVars in that code segment above was used for this purpose (byte sequences of code were returned so we could know the length but any references to symbols just used 0).
Not to discourage you, but there are already many assemblers with various bells and whistles. Please consider contributing to an existing open source project like elftoolchain.