What is the purpose of 'n = n'? - fortran

I am reading some Fortran code, and every so often the previous programmer throws in the statement 'n = n'. What is the purpose of this? Some example code:
if (cmult.lt.5.) then
kx = 0
do k=ipd(ii),lpd(ii)
kx = kx + 1
p1(kx) = epp_rfc(ipp,k)
epp_rfc(ipp,k) = cmult*epp_rfc(ipp,k) + x
zero(ix)
p2(kx) = epp_rfc(ipp,k)
n = n
enddo
if (cmult.gt.0.) then
n = n
endif
else
nk = lpd(ii) - ipd(ii) + 1
do k=ipd(ii),lpd(ii)
kx = kx + 1
p1(kx) = epp_rfc(ipp,k)
epp_rfc(ipp,k) = pp(imem) + zero(ix)
p2(kx) = epp_rfc(ipp,k)
n = n
enddo
endif

Code like this is frequently used to allow the programmer to set a breakpoint in debuggers that don't support conditional breakpoints.
By setting a breakpoint on that line, it will only be hit if cmult.gt.0.

The fact that n = n is used for checking the value of cmult.gt.0. and is used as 'condition breakpoint' is coincidental in a sense that it's not the reason why n = n appears in the above code snippet.
The real reason why n = n is used in this case lies in the fact that scope in the source code is never translated by the most popular compilers to assembly language (the computer is not smart enough to understand what 'scope' is unless its explicitly programmed by the programmer and if it did the programs will run 100s of time slower ... because of the extra instructions emitted for the logic to support scoping). It's only there to constraint the programmer in the source code and introduce a structure to the code so that linker & compiler can do their job - or issue error if violate scoping.
Because scope doesn't exist enddo cannot be paused at unless the comipler takes care to insert some instruction(like nop) and debug symbols for it to magically allow the debugger to stop at enddo. Without n = n the outcome of this line p2(kx) = epp_rfc(ipp,k) cannot be checked as the values reset at the top of the loop. This is why n = n is used to stop after the p2(kx) = epp_rfc(ipp,k) and check the final result on each itteration. After it when this code comes:
if (cmult.gt.0.) then
n = n
endif
is used for convenience (again you cannot stop at endif or else) purposes and yes this is kind of conditional breakpoint. But n = n is again used because you cannot stop after checking if (cmult.gt.0.) - you can stop at it but not after it - the next instruction will be after the outer if else. I hope this makes sense.
Edit: If it still doesn't make too much sense here is additional info: in order to check the value of p2(kx) after p2(kx) = epp_rfc(ipp,k) has executed the debugger has to emit instructions to check/fetch it - hence it is required to know a) what is the size of p2(kx) b) it's location - remember the last instruction(s)! and c) emit the appropriate instructions to fetch the value p2(kx). All to complicated for the debugger as this is actually logic - the debugger has to be 'smart' (falls into AI domain), if a debugger could do this Terminator would have existed by now.

Related

SystemVerilog, if-statements order inside an always_comb block

I am new to SystemVerilog and I would like to know how multiple assignments to the same signal are handled inside an always_comb block.
I am analyzing an FSM written by someonelse and I don't understand which would be the next state (signal named "ctrl_fsm_ns") if all the if-statements are true. Searching on google, I found out that here blocking assignments are used, so I expect that the last if-statement will decide the next state (so it is like a certain priority is assigned to each if-statement). But what if inside each if-block different signals are asserted? They will be all asserted even if the next state will be the last one, for example?
Here is the piece of code I don't understand.
always_comb
begin
...
unique case (ctrl_fsm_cs)
...
FIRST_FETCH:
begin
is_decoding_o = 1'b0;
// Stall because of IF miss
if ((id_ready_i == 1'b1) )
begin
ctrl_fsm_ns = DECODE;
end
// handle interrupts
if (irq_req_ctrl_i & irq_enable_int) begin
// This assumes that the pipeline is always flushed before
// going to sleep.
ctrl_fsm_ns = IRQ_TAKEN_IF;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
end
if ((debug_req_pending || trigger_match_i) & (~debug_mode_q))
begin
ctrl_fsm_ns = DBG_TAKEN_IF;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
end
end
Your question to the code above is a general programming question and not Verilog-specific. Because there are only blocking assignments in use, the code is entirely procedural.
Since the code isn't using an "if-else-if" sequence, but just "if-if-if", all the "if" conditions will be evaluated IN ORDER, and all assignments will happen IN ORDER, thus the final assignment will win out (as Dave said).
In your comments above you asked about what if (A_expr,B_expr,C_expr) where all true? Then (A,B,C) will all be set to 1.
A_expr=1; B_expr=1; C_expr=1;
if (A_expr) A = 1;
if (B_expr) B = 1;
if (C_expr) C = 1;
For each variable in the always_comb block, the last assignment is the final value. The tool analyzes the procedural flow to make sure every variable that is being assigned has at least one assignment in every possible flow through the code. If there is any possibility that a variable could be read without being written to, that is considered latch behavior and would be illegal for an always_comb block.
You need to look at the code before or after the case statement to see if there are any other assignments to the halt_ variables.
An example based on your comments:
always_comb begin
A = 0; B = 1; C = 2;
if (I) A = X;
if (J) B = Y;
if (K) begin B = Z; C = Z; end
end
That is equivalent to these three continuous assignments:
assign A = I ? X : 0;
assign B = K ? Z : (J ? Y : 1 );
assign C = K ? Z : 2;
Each if statement becomes a multiplexor, and the latter statements have the higher priority.

Lua game development, table seems to delete itself after each interation

What I am trying to do is a little addon which would let me know how much time I have spent casting during combat in %,
function()
local spell, _, _, _, _, endTime = UnitCastingInfo("player")
-- getting information from the game itself whether im "Casting"
local inCombat = UnitAffectingCombat("player")
-- getting information form the game if combat is true (1) or not (nil)
local casting = {}
local sum = 0
if inCombat == 1 then
if spell then
table.insert(casting, 1)
else
table.insert(casting, 0)
end
else
for k in pairs (casting) do
casting [k] = nil
end
end
for i=1, #casting, 1 do
sum = sum + casting[i]
end
return( sum / #casting ) end
-- creating a list which adds 1 every frame I am casting and I am in combat,
-- or adds 0 every frame I'm not casting and I'm not in combat.
-- Then I sum all the numbers and divide it by the number of inputs to figure
-- out how much % I have spent "casting".
-- In case the combat condition is false, delete the list
For some reason these numbers don't add up at all, I only see "1" when both conditions are satisfied, or 0 if the combat condition is satisfied.
There might be some better approach I'm sure, but I am kind of new to lua and programming in general.
You say you're new to Lua, so I will attempt to explain in detail what is wrong and how it can be improved, so brace yourself for a long read.
I assume that your function will be called every frame/step/tick/whateveryouwanttocallit of your game. Since you set sum = 0 and casting = {} at the beginning of the function, this will be done every time the function is called. That's why you always get 0 or 1 in the end.
Upvalues to the rescue!
Lua has this nice thing called lexical scoping. I won't go into much detail, but the basic idea is: If a variable is accessible (in scope) when a function is defined, that function remembers that variable, no matter where it is called. For example:
local foo
do
local var = 10
foo = function() return var end
end
print(bar) -- nil
print(foo()) -- 10
You can also assign a new value to the variable and the next time you call the function, it will still have that new value. For example, here's a simple counter function:
local counter
do
count = 0
counter = function() count = count + 1; return count; end
end
print(counter()) -- 1
print(counter()) -- 2
-- etc.
Applying that to your situation, what are the values that need to persist from one call to the next?
Number of ticks spent in combat
Number of ticks spent casting
Define those two values outside of your function, and increment / read / reset them as needed; it will persist between repeated calls to your function.
Things to keep in mind:
You need to reset those counters when the player is no longer casting and/or in combat, or they will just continue where they left off.
casting doesn't need to be a table. Tables are slow compared to integers, even if you reuse them. If you need to count stuff, a number is more than enough. Just make casting = 0 when not in combat and increase it by 1 when in combat.
Thank you for feedback everyone, in the end after your suggestions and some research my code looks like this and works great:
function()
local spell, _, _, _, startTime, endTime, _, _, _ = UnitCastingInfo("player")
local inCombat = UnitAffectingCombat("player")
local inLockdown = InCombatLockdown()
local _, duration, _, _ = GetSpellCooldown("Fireball")
casting = casting or {}
local sum = 0
if inCombat == 1 or inLockdown == 1 then
if spell or duration ~= 0 then
casting[#casting+1] = 1
elseif spell == nil or duration == 0 then
casting[#casting+1] = 0
end
else
local next = next
local k = next(casting)
while k ~= nil do
casting[k] = nil
k = next(casting, k)
end
end
for i=1, #casting, 1 do
sum = sum + casting[i]
end
return(("%.1f"):format( (sum / #casting)*100 ).. "%%") end
what i noticed is there was a problem with reseting the table in the original code:
for k in pairs (casting) do
casting [k] = nil
it seemed like either some zeros stayed there, or the table size didnt "shrink" i dont know.
Maybe intereger would be faster then a table, but honestly i dont see any performance issues even when the table gets ridicolously big (5 min, 60 fps, thats 18k inputs) also for the sake of learning a new language its better to do it harder way in my opinion
Regards

Bit wise 'AND' an array of registers in Verilog

I have an array of registers/buses and a single result bus defined as follows.
wire [BW-1:0] bus_array[NUM-1:0];
reg [BW-1:0] and_result;
where
parameter BW = 4;
parameter NUM = 8;
I wish to perform a BW-bit AND operation on the elements of the array and assign the result to the register and_result.
I try doing this as follows.
integer l;
generate
genvar m;
for (m=0; m<BW; m=m+1)
begin : BW_LOOP
always # (*)
begin
and_result[m] = 1'b1;
for (l=0; l<NUM; l=l+1)
and_result[m] = and_result[m] & bus_array[l][m];
end
end
endgenerate
However when I simulate this in Modelsim 10.1e, I get the following error.
Error: (vsim-3601) Iteration limit reached at time 2 ns
If I do not use the generate loop, and instead have BW instances of the always # (*) block, the simulation works okay.
I can infer from the error message, that there is a problem with the generate for loop, but I am not able to resolve the problem.
Most likely a bug with ModelSim. Reproducible on EDAplayground with ModelSim10.1d. Works fine with Riviera2014 (After localizing l inside the generate loop). I'm guessing that and_result[m] is somehow in the #(*) sensitivity list, which it shouldn't be.
l needs to be localized or it will be accessed in parallel with the generated always blocks; creating a potential raise condition.
One workaround is to use SystemVerilog and use always_comb instead of always #(*).
A backwarnd compatable solution is to change and_result[m] = and_result[m] & bus_array[l][m]; to if (bus_array[l][m]==1'b0) and_result[m] = 1'b0; which is equivalent code. This keeps and_result[m] only on as a left hand expression so it cannot be in the sensitivity list.
genvar m;
for (m=0; m<BW; m=m+1)
begin : BW_LOOP
integer l; // <== 'l' is local to this generate loop
always # (*)
begin
and_result[m] = 1'b1;
for (l=0; l<NUM; l=l+1) begin
if (bus_array[l][m]==1'b0) begin
and_result[m] = 1'b0;
end
end
end
Working code here

difference between 'when' and 'if' in OpenModelica?

I'm new to OpenModelica and I've a few questions regarding the code of 'BouncingBall.mo' which is distributed with the software as example code.
1) what's the difference between 'when' and 'if'?
2)what's the purpose of variable 'foo' in the code?
3)in line(15) - "when {h <= 0.0 and v <= 0.0,impact}",, shouldn't the expression for 'when' be enough as "{h <= 0.0 and v <= 0.0}" because this becomes TRUE when impact occurs, what's the purpose of impact(to me its redundant here) and what does the comma(,) before impact means?
model BouncingBall
parameter Real e = 0.7 "coefficient of restitution";
parameter Real g = 9.81 "gravity acceleration";
Real h(start = 1) "height of ball";
Real v "velocity of ball";
Boolean flying(start = true) "true, if ball is flying";
Boolean impact;
Real v_new;
Integer foo;
equation
impact = h <= 0.0;
foo = if impact then 1 else 2;
der(v) = if flying then -g else 0;
der(h) = v;
when {h <= 0.0 and v <= 0.0,impact} then
v_new = if edge(impact) then -e * pre(v) else 0;
flying = v_new > 0;
reinit(v, v_new);
end when;
end BouncingBall;
OK, that's quite a few questions. Let me attempt to answer them:
What is the difference between when and if.
The questions inside a when clause are only "active" at the instant that the conditional expressions used in the when clause becomes active. In contrast, equations inside an if statement are true as long as the conditional expression stays true.
What's the purpose of foo?
Probably for visualization. It has no clear impact on the model that I can see.
Why is impact listed in the when clause.
One of the problems you have so-called Zeno systems like this is that it will continue to bounce indefinitely with smaller and smaller intervals. I suspect the impact flag here is meant to indicate when the system has stopped bouncing. This is normally done by checking to make sure that the conditional expression h<=0.0 actually becomes false at some point. Because event detection includes numerical tolerancing, at some point the height of the bounces never gets outside of the tolerance range and you need to detect this or the ball never bounces again and just continues to fall. (it's hard to explain without actually running the simulation and seeing the effect).
What does the , do in the when clause.
Consider the following: when {a, b} then. The thing is, if you want to have a when clause trigger when either a or b become true, you might think you'll write it as when a or b then. But that's not correct because that will only trigger when the first one becomes true. To see this better, consider this code:
a = time>1.0;
b = time>2.0;
when {a, b} then
// Equation set 1
end when;
when a or b then
// Equation set 2
end when;
So equation set 1 will get executed twice here because it will get executed when a becomes true and then again when b becomes true. But equation set 2 will only get executed once when a becomes true. That's because the whole expression a or b only becomes true at one instant.
These are common points of confusion about when. Hopefully these explanations help.

Generate Block Compile Time If-Else Parameterized

I'm looking to be able to parametric some behavioral level Verilog using the generate block. The module is for a re-configurable readout and FIFO block, mainly so we can code this up one and just use a parameter at the top level.
Lets say we have:
always #(posedge write_out_clk or posedge RESETN)
begin
if (RESETN)
SENSE_ADDR <= 0;
else if (enb[0] == 1)
SENSE_ADDR <= 1; // for example but may be some other wire/bus etc
else if (enb[1] == 2)
SENSE_ADDR <= 1; // for example but may be some other wire/bus etc
else
SENSE_ADDR <= SENSE_ADDR;
end
end
This is behavioral so the specifics of implementation are left to the compiler with user given timing constraints etc. This works for 'n' else-if statements within the block if I hard code them, currently synthesis and simulation are both working for 16 statements.
My question however is how to parameterise this using generate? Clearly if 'n=8' its not too much of a big deal to hard code it. What if 'n=64' or 'n=128' etc. Seems a shame to hard code it if the rest of the module is fully parameterized using the generate for 'n'...
I have tried doing something like:
genvar elseif_generate;
generate
for (elseif_generate=0; elseif_generate<FIFO_SUB_BLOCKS; elseif_generate=elseif_generate+1)
begin: elseif_generate_logic
always #(posedge write_out_clk or posedge RESETN)
begin
if (RESETN)
SENSE_ADDR <= 0;
else if (enb[elseif_generate] == 1)
SENSE_ADDR <= some_wire[elseif_generate];
else
SENSE_ADDR <= SENSE_ADDR;
end
end
endgenerate
This however leads to Multi-source errors for the output wire 'SENSE_ADDR'. This leads me to the further question. Clearly a generate block is not suitable here but how would I go about implementing parameterised code replication for this block? Basically I want the functionality of the behavioral, hard coded if-else always block in a parameterised form...
Does this serve your needs? No generate required.
module mux #(
parameter WIDTH = 5,
parameter NUM = 2,
parameter NUMLG = $clog2(NUM)
) (
input [NUMLG -1:0] sel,
input [WIDTH - 1:0] in [0:NUM-1],
output [WIDTH - 1:0] out
);
assign out = in[sel];
endmodule
If your simulator doesn't support SystemVerilog that well you'll have to modify this to blow out the input array but the concept is the same.
You don not need a generate block. Add a combination always block to calculate next_SENSE_ADDR that will be flopped to SENSE_ADDR.
always #(posedge write_out_clk or posedge RESETN)
begin
if (RESETN)
SENSE_ADDR <= 0;
else
SENSE_ADDR <= next_SENSE_ADDR;
end
integer idx;
always #* begin // #(SENSE_ADDR or enb or some_wire)
next_SENSE_ADDR = SENSE_ADDR; // default, value if enb is all 0
// count down because lsb has higher priority
for ( idx=FIFO_SUB_BLOCKS-1; idx>=0; idx-- ) begin
if ( enb[idx] )
next_SENSE_ADDR = some_wire[idx];
end
end