wire in always block/case statement - Verilog - case

Following is a sample code that uses case statement and always #(*) block. I don't get how the always block is triggered and why it works even when x is declared as wire.
wire [2:0] x = 0;
always #(*)
begin
case (1'b1)
x[0]: $display("Bit 0 : %0d",x[0]);
x[1]: $display("Bit 1 : %0d",x[1]);
x[2]: $display("Bit 2 : %0d",x[2]);
default: $display("In default case");
endcase
end
Any help is appreciated.
Thanks.

As we know, reg can be driven by a wire, we can definitely use a wire as the right hand side of the assignment in any procedural block.
Here, your code checks which bit of x is 1'b1 (of course giving priority to zeroth bit). Lets say x changes to 3'b010. Then, Bit 1 shall be displayed and so on. Now, if x=3'b011 then Bit 0 is displayed since zeroth bit is checked first.
As you can see, there is no assignment to x, the procedural block only reads its value. Moreover, the system task $display also reads the value of x.
There is no change of signal value from this block. Hence, this code works fine. If, by chance, we had something like x[0] = ~x[0] instead of $display, then this code shall provide compilation issues.
More information can be found at this and this links.

Here, this always block does not assign a value to a x, but it just checks a value of x. So it's a legal use of wire.

So, the explanation to the part of your question about how always #(*) is triggered is as follows :
"Nets and variables that appear on the right-hand side of assignments, in subroutine calls, in case and conditional expressions, as an index variable on the left-hand side of assignments, or as variables in case item expressions shall all be included in always #(*)."
Ref: IEEE Std 1800-2012 Sec 9.4.2.2
As an extension of #sharvil111's answer, if your code was something like this
always #(*)
begin
case (sel)
x[0]: $display("Bit 0 : %0d",x[0]);
x[1]: $display("Bit 1 : %0d",x[1]);
x[2]: $display("Bit 2 : %0d",x[2]);
default: $display("In default case");
endcase
end
The procedural block would be triggered whenever there is a change in sel signal or x i.e. it would be equivalent to always #(sel or x).

Related

Vim - mapping a key to a function which does something else plus the orginal function of that key

The target is to have the key j doing a possibly complex task and moving to the next line (the latter action performed just like the original function of the j key).
My initial attempt was to map j key this way:
nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>
(as you can see I intend to make j's behavior depend on the count which is prepended to it)
and to define the function MyFun appropriately:
fu! MyFun(count)
" do more stuff based on a:count
normal j
endf
which is faulty, as hitting j now results in the error E169: Command too recursive, since the non-recursivity of nnoremap, as long as my deduction is correct, applies to the "literal" content of the {rhs} of the mapping, and not to whatever is "inside" it (in other words the function body makes use of the meaning of j at the moment it is called, thus causing the infinte recursion).
Therefore I tried the following
nn , j
nn j :<C-U>execute "call MyFun(" . v:count . ")"<CR>
fu! MyFun(count)
" do more stuff based on a:count
normal ,
endf
However this means that I waste the key ,. I know I can avoid the waste of that mapping doing
nn <Plug>Nobody j
but then I wouldn't know how to use <Plug>Nobody (my understanding is indeed that its use is only in the {rhs} of another, non-nore mapping).
My initial attempt was to map j key this way
Using execute here is redundant. It's enough to do:
nnoremap j :<C-U>call MyFun(v:count)<CR>
now results in the error E169: Command too recursive
That's because of normal. To suppress remapping you must use "bang"-form: normal! j. Please, refere
to documentation for :normal, whose second paragraph describes exactly your use case:
If the [!] is given, mappings will not be used. Without it, when this
command is called from a non-remappable mapping (:noremap), the
argument can be mapped anyway.
Besides, note that j normally supports count, so 2j is expected to move two lines down. So you, probably, should do execute 'normal!' a:count . 'j' instead.

KEYWORD_SET in IDL

I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF

fpga programming using verilog

Case statement in verilog. I don't understand how this code works
if(cpld_cs & cpld_we)
begin
case(ifc_a27_31)
`RSTCON1: begin
sw_rst_r <= ifc_ad0_7[0];
ddr_rst_r <= ifc_ad0_7[1];
ec1_rst_r <= ifc_ad0_7[2];
ec2_rst_r <= ifc_ad0_7[3];
xgt1_rst_r <= ifc_ad0_7[6];
xgt2_rst_r <= ifc_ad0_7[7];
Just look up documentation. I am no verilog expert but checking documentation you can get that
case(ifc_a27_31)
`RSTCON1: begin
is just simple case where if value of ifc_a27_31 is RSTCON1 then commands
sw_rst_r <= ifc_ad0_7[0];
ddr_rst_r <= ifc_ad0_7[1];
ec1_rst_r <= ifc_ad0_7[2];
ec2_rst_r <= ifc_ad0_7[3];
xgt1_rst_r <= ifc_ad0_7[6];
xgt2_rst_r <= ifc_ad0_7[7];
are getting executed.
And of course
sw_rst_r <= ifc_ad0_7[0];
is just non-blocking assignment.
Information I took from Case Statement and What is the difference between = and <= in verilog?
verilog case syntax consists of a case expression or selector expression (ifc_a37_31) and case items with label expression (macro RSTCON1 in your case) and action items. When afr_a37_31 matches the value of the macro, the statements in the begin .. end block will be executed sequentially.
The case statement might have multiple case items, the first one which matches the selector will be active and its block will be executed.
There is also a default clause which will get executed if no matches are found.
Now in your case it looks like this is a part of a latch or a flop definition, since 'non-blocking' assignments are used there. It is ok to miss some conditions and/or the default statement in such a case.
you might see other variants of the case statement, like casex or casez. Syntax for all of them is similar, the difference is in the ways the selector is compared to the label.
in system verilog there are more, like unique of priority cases or case inside.
So, you need to go through a tutorial to get more information about all this.

Associative array element accessing in comb vs sequential

I was trying to write a test-bench code which used an associative array, and was seeing that in one case accessing its values wasn't working as a comb logic, but when moved inside a sequential block it was working fine.
Example code :
Here "value" was getting assigned as "x" always, but once I moved it inside the #posedge block, I was seeing it assigned the right value (1 once "dummy" got assigned).
Can someone explain why this is so ?
logic dummy[logic[3:0]];
logic value;
always # (posedge clk)
begin
if (reset == 1'b1) begin
count <= 0;
end else if ( enable == 1'b1) begin
count <= count + 1;
end
if(enable) begin
if(!dummy.exists(count))
begin
dummy[count] = 1;
$display (" Setting for count = %d ", count);
end
end
end
always_comb begin
if(dummy.exists(count)) begin
value = dummy[count];
$display("Value = %d",value);
end else begin // [Update : 1]
value = 0;
end
end
[UPDATE : 1 - code updated to have else block]
The question is a bit misleading, actually the if(dummy.exist(count)) seems to be failing when used inside comb logic, but passes when inside seq logic (and since "value" is never assigned in this module, it goes to "x" in my simulation - so edited with an else block) - but this result was on VCS simulator.
EDA-playground link : http://www.edaplayground.com/x/6eq
- Here it seems to be working as normally expected i.e if(dummy.exists(count)) is passing irrespective of being inside always_comb or always #(posedge)
Result in VCS :
[when used as comb logic - value never gets printed]
Value = 0
Applying reset Value = 0
Came out of Reset
Setting for count = 0
Setting for count = 1
Setting for count = 2
Setting for count = 3
Setting for count = 4
Terminating simulation
Simulation Result : PASSED
And value gets printed as "1" when the if(dummy.exist(count)) and assignment is moved inside seq block.
Your first always block contains both blocking and non-blocking assignments, which VCS may be allowing because the always keyword used to be able to specify combinational logic in verilog (via always #(*)). This shouldn't account for the error, but is bad style.
Also the first line of your program is strange, what are you trying to specify? Value is a bit, but dummy is not, so if you try doing dummy[count] = 1'b1, you'll also pop out an error (turn linting on with +lint=all). If you're trying to make dummy an array of 4 bit values, your syntax is off, and then value has the wrong size as well.
Try switching the first always to an explicit always_ff, this should give you a warning/error in VCS. Also, you can always look at the waveform, compile with +define+VPD and use gtkwave (freeware). This should let you see exactly what's happening.
Please check your VCS compilation message and see if there is any warning related to SV new always_comb statement. Some simulators might have issues with the construct or do not support that usage when you inferred "dynamic types" in the sensitivity list. I tried with Incisiv (ncverilog) and it is also OK.

The use of IN OUT in Ada

Given below is some code in ada
with TYPE_VECT_B; use TYPE_VECT_B;
Package TEST01 is
procedure TEST01
( In_State : IN VECT_B ;
Out_State : IN OUT VECT_B );
function TEST02
( In_State : IN VECT_B ) return Boolean ;
end TEST01;
The TYPE_VECT_B package specification and body is also defined below
Package TYPE_VECT_B is
type VECT_B is array (INTEGER range <>) OF BOOLEAN ;
rounded_data : float ;
count : integer ;
trace : integer ;
end TYPE_VECT_B;
Package BODY TYPE_VECT_B is
begin
null;
end TYPE_VECT_B;
What does the variable In_State and Out_State actually mean? I think In_State means input variable. I just get confused to what actually Out_State means?
An in parameter can be read but not written by the subprogram. in is the default. Prior to Ada 2012, functions were only allowed to have in parameters. The actual parameter is an expression.
An out parameter implies that the previous value is of no interest. The subprogram is expected to write to the parameter. After writing to the parameter, the subprogram can read back what it has written. On exit the actual parameter receives the value written to it (there are complications in this area!). The actual parameter must be a variable.
An in out parameter is like an out parameter except that the previous value is of interest and can be read by the subprogram before assignment. For example,
procedure Add (V : Integer; To : in out Integer; Limited_To : Integer)
is
begin
-- Check that the result wont be too large. This involves reading
-- the initial value of the 'in out' parameter To, which would be
-- wrong if To was a mere 'out' parameter (it would be
-- uninitialized).
if To + V > Limited_To then
To := Limited_To;
else
To := To + V;
end if;
end Add;
Basically, every parameter to a function or procedure has a direction to it. The options are in, out, in out (both), or access. If you don't see one of those, then it defaults to in.
in means data can go into the subroutine from the caller (via the parameter). You are allowed to read from in parameters inside the routine. out means data can come out of the routine that way, and thus you are allowed to assign values to the parameter inside the routine. In general, how the compiler accomplishes the data passing is up to the compiler, which is in accord with Ada's general philosophy of allowing you to specify what you want done, not how you want it done.
access is a special case, and is roughly like putting a "*" in your parameter definition in Cish languages.
The next question folks usually have is "if I pass something large as an in parameter, is it going to push all that data on the stack or something?" The answer is "no", unless your compiler writers are unconsionably stupid. Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine. Again, you tell Ada what you want done, it figures out the most efficient way to do it.

Resources