Can a Verilog In line Initialization cause an event? - verilog

Since in-line variable initialization will be executed during simulation time 0.Is there a chance that it might trigger an event at time 0 ? Please elaborate

Variable 'initialization' will always trigger an event. From the last Verilog standard(IEEE 1364-2005):
If a variable declaration assignment is used (see 6.2.1), the variable
shall take this value as if the assignment occurred in a blocking
assignment in an initial construct.
Also be aware
If the same variable is assigned different values both in an initial
block and in a variable declaration assignment, the order of the
evaluation is undefined.

A good reference for order of events is this paper:
http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf
page 6 has a diagram of the order of events as far as evaluation of variables and triggering goes.

Related

FreeRTOS: How could xSemaphoreTakeFromISR wake any Task

New to FreeRTOS and trying to understand it in detail.
According to the manual here...:
https://www.freertos.org/xSemaphoreTakeFromISR.html
... it is possible that calling xSemaphoreTakeFromISR can cause waking up some Task from blocked state.
How is this possible ?
How could some task get to the blocked state by calling xSemaphoreGive in the first place ?
I understand, that semaphores and mutex are implemented by Queues and xQueueSend has a parameter xTicksToWait (which set to value portMAX_DELAY can cause this function to get to blocked state).
But all inner implementations of xSemaphoreGive set this parameter (xTicksToWait) to zero.
Please explain, why should I check the parameter pxHigherPriorityTaskWoken in xSemaphoreTakeFromISR, and in which rare occasion it can be set to pdTRUE ?

SystemVerilog calculations right before writing to clocking block

I have a task, whose job it is to drive data onto a bus via a clocking block. See snippet:
task effects_driver::ReadQueueData();
stream_intf_.cycles(); // clocking block event
if (sample_q_.size() >= 2) // check to see if there is enough data in the queue
begin
automatic bit [31:0] sample0, sample1;
sample0 = sample_q_.pop_front(); // read from queue
sample1 = sample_q_.pop_front(); // read from queue
stream_intf_.cb.AXIS_TDATA <= {sample1, sample0}; // drive two samples at once
stream_intf_.cb.AXIS_TVALID <= 1;
end
else
...
endtask
You'll notice that I need to read a couple of items out of a queue before writing it to the clocking block. Is this the correct way to do it? Am I guaranteed that the simulator will perform these blocking assignments to the automatic variable before writing it to the clocking block?
P.S. I run into this scenario semi-frequently--where I need to do some quick calculations on the fly right before writing to the clocking block.
I believe you meant to ask "Am I guaranteed that the simulator will perform these blocking assignments to the automatic variable before writing it to the clocking block?" because that is what your code is doing.
The answer to that is yes, blocking assignments are guaranteed to complete before executing the statement following it.
Also note that there is no need to declare sample0 and sample1 with automatic lifetimes because class methods always have automatic lifetimes. Variables declared within them are implicitly automatic.

How does SystemVerilog `force` work?

I have a hierarchy of modules where I am trying to do a force to get different value at different module interface. I am working on a component whose task is to inject transaction to a module down the hierarchy, bypassing the drives from the modules higher up in the hierarchy. I thought I could use force on the control signals in order to disengage drives from higher up modules and start driving into the module of interest. So I have been trying to see how force will work. The full code is at http://www.edaplayground.com/x/69PB.
In particular, I am trying to understand effect of these two statements within initial block:
force u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid = 1'b0;
force u_DataReceiveTop.valid = 1'b1;
what I expected the values to be is:
u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 0
u_DataReceiveTop.valid == 1
but I see from waves:
u_DataReceiveTop.u_DataReceiveWrap.DataReceiveIfWrp_inst.valid == 1
u_DataReceiveTop.valid == 1
It is as if the second force statement force u_DataReceiveTop.valid = 1'b1; has propagated down the hierarchy even though there is another force. What is happening here?
A wire in Verilog is a network of drivers and receivers all connected to the same signal. The value of that signal is some resolution function of all the drivers and the type of the wire. When you connect two wires through a port, the two wires get collapsed into a single signal, but you still have two different names for the same signal.
When you use the force statement on a wire, that overrides all the drivers on the network until encountering another force or release statement. In your example, the second force statement replaces the first force. I doesn't matter which hierarchical reference you use in the force because they all refer to the same signal.
If you want the behavior you are expecting, you need to use variables instead of wires. When you connect a variable to a port, SystemVerilog creates an implicit continuous assignment, depending on the direction of the port. SystemVerilog does not allow more than one continuous assignment to a variable, which is why you can't use variables with an inout port. So you will need to be more careful about the port directions then.

Parameterized FIFO instantiation in Verilog

I wanted to have a parameterized FIFO instantiation so that I can call a single FIFO instance with change in depth(parameter).
e.g. I have written a code for FIFO with depth as a parameter.
I will know the depth of the FIFO only by the configuration from Microprocessor. Based on the register configuration, can i call this FIFO with variable parameter like value?
integer depth_param;
if(config_reg[1])
depth_param <= 128;
else
depth_param <= 512;
genfifo #(depth_param) (.din (din),.wr(wr)....);
fifo module is:
module gen_fifo #(depth = 128)
( din,wr,rd,clk....);
can you please suggest is there a way I can do this?
This is what the LRM says:
Parameters represent constants; hence, it is illegal to modify their
value at run time. However, module parameters can be modified at
compilation time to have values that are different from those
specified in the declaration assignment. This allows customization of
module instances. A parameter can be modified with the defparam
statement or in the module instance statement. Typical uses of
parameters are to specify delays and width of variables.
'run time' means during simulation, after elaboration. A synthesiser doesn't 'run' anything, but what you're doing is effectively "run time", and so is illegal.
This doesn't mean that you can't do it, though. Pass in your FIFO depth as a module port. I'm assuming that you know how to code a FIFO from first principles. If so, you will normally have a constant for the FIFO size; just replace this constant with the value at the port, and find some way to set the memory size. You'll obviously need to be careful when changing the FIFO size - you may need to reset it, for example. If you don't know how to code a FIFO you should ask with an FPGA or an electronics tag.

Verilog specify block within for-loop

I am trying to model path delays for an n-bit wide signal. I can do this fine if I explicitly define the delay for each individual bit, like this (n=3):
specify
(in_data[0] => delayed_data[0]) = 5;
(in_data[1] => delayed_data[1]) = 2;
(in_data[2] => delayed_data[2]) = 1;
endspecify
However, I want to be able to specify random delays for each bit of in_data when in_data is n-bits wide. My idea was something like this:
for (n=0;n<DATA_WIDTH-1;n=n+1)
begin
specify
(in_data[n] => delayed_data[n]) = {$random};
endspecify
end
This gives me an error: "near 'specify': syntax error, unexpected specify"
I also tried placing the for loop within the specify block. This resulted in the following error: "near 'begin': syntax error, unexpected begin, expecting endspecify"
I would really appreciate any tips on how to do this correctly
According to the Doulos Verilog Reference Guide (page 84) a specify block can only occur within module and endmodule tags, and not within anything else.
According to this Verilog reference website:
The Specify block was designed to define a delay across a module. It starts with specify and ends with the endspecify keyword. Inside the block the user can specify: specparam declaration, path declaration or system timing check.
This seems to imply it does not allow for-loops within specify blocks.
Hence it leads me to believe that you'll need to write out all the values one by one due to a limitation of the language.
One idea you could try is to restructure your modules to have a one bit input to a one bit output. Then each specify block will only have one delay to specify, and you can assign them each a random value. You can then generate these modules inside a generate block which will avoid you having to specify a delay for each bit manually.
However, this may be more tedious/awkward.

Resources