Is it possible to use enum with don't cares? I've tried the following
typedef enum reg [31:0] {
BLTZ = 32'b000001_?????_00000_????????????????,
BGEZ = 32'b000001_?????_00001_????????????????,
BEQ = 32'b000100_?????_?????_????????????????,
BNE = 32'b000101_?????_?????_????????????????,
.
.
.
Then using the syntax given by doulos.com, I tried the following to see if I can get an "ADD" instruction to be displayed on the waveform viewer
op_mne_e op_mnemonic;
assign op_mnemonic = op_mne_e'(32'b000000_?????_?????_?????_?????_10000);
but what I see is
000000zzzzzzzzzzzzzzzzzzzz10000
Is it possible to have something similar to a casez for enum?
I have edited the tags to this question, because you are asking about System-Verilog, not Verilog. What we call Verilog is now a subset of the System-Verilog standard, IEEE-1800.
In System-Verilog, enumeration types have an underlying base type. By default this type is int, which is a 2-state type (each bit can only take the values 0 or 1). You can specify other base types if you wish. Each member of the enumeration type is represented by a different value of the type of the base type.
You have specified a 4-state, 32-bit base type: reg [31:0]*. Those 4 states are 0, 1, Z (or ?) and X. So, each member of the enumeration type is represented by a 4-state value, ie some combination of 0, 1, Z (or ?) and X. But, when you display the value with a "%b" format specifier, that's what you get: you get the underlying 4-state value (using Zs, not ?s).
http://www.edaplayground.com/x/3khr
In a casez statement, a Z or a ? represents a don't care. So, you can use an such an enum with a 4-state base type in a casez statement if you wish:
casez (op_mnemonic)
BLTZ : $display("BLTZ");
BGEZ : $display("BGEZ");
BEQ : $display("BEQ");
BNE : $display("BNE");
endcase
but, as we're speaking System-Verilog here, why not use case ... inside instead?
case (op_mnemonic) inside
BLTZ : $display("BLTZ");
BGEZ : $display("BGEZ");
BEQ : $display("BEQ");
BNE : $display("BNE");
endcase
http://www.edaplayground.com/x/4g3J
case ... inside is usually considered safer than the old casez, because it exhibits asymmetrical wildcard matching. In other words, unlike in a casez, in a case ... inside an X or Z (or ?) in the test expression (op_mnemonic in this case) does not act like a don't care (but does in the branch expression, of course).
*It would be more usual in System-Verilog to specify logic [31:0], which is identical, but logic is usually used in System-Verilog in preference to reg.
If you want the labels of your enum variable displayed in the waveform, you will need to set the radix to display it. Most tools default to displaying in binary. SystemVerilog has a number of operators that treat 'z' as a don't care (casez is one of them) so '?' is allowed as part of a numeric literal in place of a 'z'. However, that '?' gets immediately converted over to a 'z' and you will never see a '?' printed out.
If you are trying to assign a value to an enum and have it decode the instruction and pick a matching label, that won't work. You would need to loop the the enum values and use the wildcard equality operator ==? to find a match.
But if you are only doing this to get a label in the waveform, Modelsim/Questa has a radix define command that will decode the instruction for you.
Related
At first, I thought that set! assignment in scheme is more like assignment = in python other than in c/c++.
in python:
>>> x = 1
>>> id(x)
15855960
>>> x = 2
>>> id(x)
15855936 # different from above!
the second assignment means rebind variable/name to another value instead of overwrite original value in memory location of x.
But c/c++ is the latter case:
int x = 1;
cout << &x << endl; // 0x7ffe3e6adba4
x = 2;
cout << &x << endl; // 0x7ffe3e6adba4 (the same memory location!)
But in 1.3 section of R6RS:
Scheme allows identifiers to stand for locations containing
values. These identifiers are called variables. In many
cases, specifically when the location’s value is never modified
after its creation, it is useful to think of the variable
as standing for the value directly.
And in 1.8 Assignment section:
Scheme variables bound by definitions or let or lambda
expressions are not actually bound directly to the objects
specified in the respective bindings, but to locations
containing these objects. The contents of these locations
can subsequently be modified destructively via assignment.
So it seems in scheme assignment set! is just like what c/c++ assignment = does?
But then how to explain the following:
=> (define x 10)
=> x
10
=> (set! x "lonnnnnnnnnnnnng")
=> x
"lonnnnnnnnnnnnng"
At first x is a location to store an small integer. But later set! put a LONG string into that SMALL memory location? But the location have no enough memory space to do that I think?
Both the citations from the manual say the same thing: an identifier (e.g. a thing like x or y), is associated (“bound”) to a location (a memory cell, e.g. the cell at address 0x7ffe3e6adba4), that can hold different values (for instance an integer, a string etc.), and that the content of the location can be modified with a new value. That is:
Identifier -> Location -> Value
The value, depending from the combination language/compiler, can be either a direct value (or an “unboxed” values, as sometimes it is called, typically in case of values like integers or float), or a “boxed” value, that is a pointer to some memory area the contains the value (typically for complex values like cons cells, arrays, strings, etc.).
As I said, the key point is that the implementation is free to chose how to store values in location, for instance if use a uniform method of storing values according to their type, if optimize and allocate values with different strategies, etc. The only important thing is to strictly follow the specification of the language that requires the double map above. The crucial point here is that in languages like Lisp pointers are (and should remain) “invisible” to the user (the programmer).
I recently dealt with code using a strongly typed enum that contained negative values.
When comparing the values of the enum, I got weird results when compiling the code with Clang (3.3) while Gcc works just fine.
Here is a small example with an assert that fails.
enum class T: int { A = -1, B = 1 };
int main() {
T a = T::A, b = T::B;
assert(a < b);
}
Is this an actual bug? Or does clang behave correctly and gcc just offers some kind of legacy support?
It should be more intuitive that the following is well-formed:
T a = T::A;
assert(a == T::A);
But the equality operators (==, !=) have the same restrictions as the relational operators (<, <=, ..) [expr.eq]/1:
The == (equal to) and the != (not equal to) operators have the same semantic restrictions, conversions, and result type as the relational operators except for their lower precedence and truth-value result.
So if equality between values of a scoped enumeration type is well-defined, so should < be.
[expr.rel]/1
The operands shall have arithmetic, enumeration, or pointer type, or type std::nullptr_t.
Of course, the usual arithmetic conversions are performed on operands of arithmetic or enumeration type [expr.rel]/2, where the conversion is the identity conversion for scoped enumerations (no integral promotion, see [expr]/10 first bullet). However, [expr.rel]/5 explicitly states:
If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield
true if the specified relationship is true and false if it is false.
(emphasis mine)
Therefore, T::A < T::B should be well-formed and yield true.
As I already wrote in a comment, the assertion doesn't fail on clang++3.4 trunk 193040. I therefore assume it's a bug that has been fixed, even though I couldn't find a corresponding bug report.
I have an Ada enum with 2 values type Polarity is (Normal, Reversed), and I would like to convert them to 0, 1 (or True, False--as Boolean seems to implicitly play nice as binary) respectively, so I can store their values as specific bits in a byte. How can I accomplish this?
An easy way is a lookup table:
Bool_Polarity : constant Array(Polarity) of Boolean
:= (Normal=>False, Reversed => True);
then use it as
B Boolean := Bool_Polarity(P);
Of course there is nothing wrong with using the 'Pos attribute, but the LUT makes the mapping readable and very obvious.
As it is constant, you'd like to hope it optimises away during the constant folding stage, and it seems to: I have used similar tricks compiling for AVR with very acceptable executable sizes (down to 0.6k to independently drive 2 stepper motors)
3.5.5 Operations of Discrete Types include the function S'Pos(Arg : S'Base), which "returns the position number of the value of Arg, as a value of type universal integer." Hence,
Polarity'Pos(Normal) = 0
Polarity'Pos(Reversed) = 1
You can change the numbering using 13.4 Enumeration Representation Clauses.
...and, of course:
Boolean'Val(Polarity'Pos(Normal)) = False
Boolean'Val(Polarity'Pos(Reversed)) = True
I think what you are looking for is a record type with a representation clause:
procedure Main is
type Byte_T is mod 2**8-1;
for Byte_T'Size use 8;
type Filler7_T is mod 2**7-1;
for Filler7_T'Size use 7;
type Polarity_T is (Normal,Reversed);
for Polarity_T use (Normal => 0, Reversed => 1);
for Polarity_T'Size use 1;
type Byte_As_Record_T is record
Filler : Filler7_T;
Polarity : Polarity_T;
end record;
for Byte_As_Record_T use record
Filler at 0 range 0 .. 6;
Polarity at 0 range 7 .. 7;
end record;
for Byte_As_Record_T'Size use 8;
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_As_Record_T,
Target => Byte_T);
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_T,
Target => Byte_As_Record_T);
begin
-- TBC
null;
end Main;
As Byte_As_Record_T & Byte_T are the same size, you can use unchecked conversion to convert between the types safely.
The representation clause for Byte_As_Record_T allows you to specify which bits/bytes to place your polarity_t in. (i chose the 8th bit)
My definition of Byte_T might not be what you want, but as long as it is 8 bits long the principle should still be workable. From Byte_T you can also safely upcast to Integer or Natural or Positive. You can also use the same technique to go directly to/from a 32 bit Integer to/from a 32 bit record type.
Two points here:
1) Enumerations are already stored as binary. Everything is. In particular, your enumeration, as defined above, will be stored as a 0 for Normal and a 1 for Reversed, unless you go out of your way to tell the compiler to use other values.
If you want to get that value out of the enumeration as an Integer rather than an enumeration value, you have two options. The 'pos() attribute will return a 0-based number for that enumeration's position in the enumeration, and Unchecked_Conversion will return the actual value the computer stores for it. (There is no difference in the value, unless an enumeration representation clause was used).
2) Enumerations are nice, but don't reinvent Boolean. If your enumeration can only ever have two values, you don't gain anything useful by making a custom enumeration, and you lose a lot of useful properties that Boolean has. Booleans can be directly selected off of in loops and if checks. Booleans have and, or, xor, etc. defined for them. Booleans can be put into packed arrays, and then those same operators are defined bitwise across the whole array.
A particular pet peeve of mine is when people end up defining themselves a custom boolean with the logic reversed (so its true condition is 0). If you do this, the ghost of Ada Lovelace will come back from the grave and force you to listen to an exhaustive explanation of how to calculate Bernoulli sequences with a Difference Engine. Don't let this happen to you!
So if it would never make sense to have a third enumeration value, you just name objects something appropriate describing the True condition (eg: Reversed_Polarity : Boolean;), and go on your merry way.
It seems all I needed to do was pragma Pack([type name]); (in which 'type name' is the type composed of Polarity) to compress the value down to a single bit.
As I understand it, Ada uses 0 based indexes on its enumerated types.. So in Status_Type below, the ordinal value goes from 0 to 5.
type Status_Type is
(Undefined,
Available,
Fout,
Assigned,
Effected,
Cleared);
My question is.. what are the ordinal values for the following examples? Do they start at 0 or do they start from the ordinal value from the super type?
subtype Sub_Status_Type is Status_Type
range Available.. Effected;
subtype Un_Status_Type is Sub_Status_Type
range Fout .. Assigned;
Would Sub_Status_Type ordinal values go from 1 to 4 or from 0 to 3?
Would Un_Status_Type ordinal values go from 3 to 4 or from 1 to 2 or from 0 to 1?
For the subtypes, a 'pos will return the same value as it would have for the base type (1..4 and 2..3 respectively, I believe). Subtypes aren't really new and different types, so much as they are the same old type, but with some extra limitations on its possible values.
But it should be noted that these values are assigned under the scenes. It really should make no difference to you what they are, unless you are using the 'val and 'pos attributes, or you are interfacing to code written outside of Ada (or to hardware).
Plus, if it does end up mattering, you should know that the situation is actually much more complicated. 'pos and 'val don't return the actual bit value the compiler uses for those enumeration values when it generates code. They just return their "ordinal position"; their offset from the first value.
By default they will usually be the same thing. However, you can change the value assignments (but not the ordinal position assignments) yourself with a for ... use clause, like in the code below:
for Status_Type use
(Undefined => 1,
Available => 2,
Out => 4,
Assigned => 8,
Effected => 16,
Cleared => 32);
The position number is defined in terms of the base type. So Sub_Status_Type'Pos(Assigned) is the same as Status_Type'Pos(Assigned), and the position values of Sub_Status_Type go from 1 to 4, not 0 to 3.
(And note that the position number isn't affected by an enumeration representation clause; it always starts at 0 for the first value of the base type.)
Incidentally, it would have been easy enough to find out by running a small test program that prints the values of Sub_Status_Type'Pos(...) -- which would also have told you that you can't use the reserved word out as an identifier.
As I understand it, Ada uses 0 based indexes on its enumerated types
Yes, it uses 0 for the indexes, or rather for the position of the values of the type. This is not the value of the enumeration literals, and not the binary representation of them.
what are the ordinal values for the following examples?
There are no "ordinal" values. The values of the type are the ones you specified. You are confusing "value", "representation", and "position" here.
The values of your Status_Type are Undefined, Available, Out, Assigned, Effected, and Cleared.
The positions are 0, 1, 2, 3, 4, and 5. These are what you can use to translate with 'Pos and 'Val.
The representation defaults to the position, but you can freely assign other values (as long as you keep the correct order). These are used if you write it to a file, or send it through a socket, or load it into a register..
I think the best way to answer your questions is in reverse:
A subtype is, mathematically speaking, a continuous subset of its parent type. So, if the type SIZES is (1, 2, 3, 4, 5, 6, 7, 8) and you define a subtype MEDIUM as (4,5) the first element of MEDIUM is 4.
Example:
Type Small_Natural is 0..16;
Subtype Small_Positive is Small_Natural'Succ(Small_Natural'First)..Small_Natural'Last;
This defines two small sets of possible-values, which are tightly related: namely that Positive numbers are all the Natural Numbers save Zero.
I used this form to illustrate that with a few text-changes we have the following example:
Type Device is ( Not_Present, Power_Save, Read, Write );
Subtype Device_State is Device'Succ(Device'First)..Device'Last;
And here we are modeling the intuitive notion that a device must be present to have a state, but note that the values in the subtype ARE [exactly] the values in the type from which they are derived.
This answers your second question: Yes, an element of an enumeration would have the same value that its parent-type would.
As to the first, I believe the starting position is actually implementation defined (if not then I assume the LM defaults it to 0). You are, however free to override that and provide your own numbering, the only restriction being that elements earlier in the enumeration are valued less than the value that you are assigning currently [IIRC].
Having setup an event tap, I'm not able to identify what modifier key was pressed given a CGEvent.
CGEventFlags flagsP;
flagsP=CGEventGetFlags(event);
NSLog(#"flags: 0x%llX",flagsP);
NSLog(#"stored: 0x%llX",kCGEventFlagMaskCommand);
if (flagsP==kCGEventFlagMaskCommand) {
NSLog(#"command pressed");
}
Given the above snippet, the first NSLog returns a different value from the second NSLog. No surprise that the conditional is never triggered when the command modifier key is pressed.
I need to identify whether command, alternate, option, control or shift are pressed for a given CGEvent. First though, I need help to understand why the above isn't working.
Thanks!
These are bit masks, which will be bitwise-ORed together into the value you receive from CGEventGetFlags (or pass when creating an event yourself).
You can't test equality here because no single bit mask will be equal to a combination of multiple bit masks. You need to test equality of a single bit.
To extract a single bit mask's value from a combined bit mask, use the bitwise-AND (&) operator. Then, compare that to the single bit mask you're interested in:
BOOL commandKeyIsPressed = (flagsP & kCGEventFlagMaskCommand) == kCGEventFlagMaskCommand;
Why both?
The & expression evaluates to the same type as its operands, which is CGEventFlags in this case, which may not fit in the size of a BOOL, which is a signed char. The == expression resolves that to 1 or 0, which is all that will fit in a BOOL.
Other solutions to that problem include negating the value twice (!!) and declaring the variable as bool or _Bool rather than Boolean or BOOL. C99's _Bool type (synonymized to bool when you include stdbool.h) forces its value to be either 1 or 0, just as the == and !! solutions do.