Verilog: initialization in hierarchical design - verilog

I have some questions about reg initialization.
Can I put Initial blocks in the design? Is that a good way?
How to initial regs in my bottom design? Do I need to create ports in each level and give initial value from top to bottom? For each simulation, initial values are different.

Point 1:
We recently had a discussion about initial statements on the Electronics forum.
Initial statements in test benches are normal. In fact without initial statements it becomes a lot more difficult to write test code.
Initial statements are not possible in ASICs, CPLDs or hard programmed FPGAs.
You can use initial statements in a most RAM based FPGAs where the state is valid after the FPGA is loaded. However if you would have a 'reset' pin or command that would not restore the initial state. As such, the FPGA condition after such a reset could well be different from your start-up state and thus your design might not work correctly.
There are some cases where an initial state in an actual synthesize-able module is allowed or even mandatory for the module to work. See examples below.
Example 1: You have a divide by two register without reset coded as:
divide_by_two <= ~divide_by_two;
or
divide_by_two <= not(divide_by_two);
In simulation that will always remain 'X' but in reality it will start in a 0 or 1 conditions and then toggle between the two. To work around the 'X' in simulation you have the set an initial condition. Your code should work independent if the initial condition is '1' or '0'.
Example 2: You have a divide by four register without reset coded as:
divide_by_four[1:0] <= {divide_by_four[0],~divide_by_four[1]};
or
divide_by_four[1:0] <= divide_by_four[0] & not(divide_by_four[1]);
The reason why this is allowed is that during operation the two registers go through every of the four possible states: 00, 01, 11, 10. It does not matter in which of the four it starts, the sequence will always be repeated. Again to work around the 'XX' in simulation you have the set an initial condition. Your code should work independent if the initial condition is 00, 01, 10 or 11.
A lot of designers feel that, apart for examples like above, the use of initial statements in synthesized code is dangerous and it is better to avoid them.
Point 2:
Instead of initial statements you can use a 'reset' signal with the appropriate HDL code to set the start condition. It is normal for the reset to go to every module which has registers.

Depends on your target design.
You can usually use initial blocks with FPGAs. You can initialization the registers in the same module that declares it. Hierarchically assignment is not allowed. You can also initialization registers with a synchronous reset if you add a reset input. Most FPGAs have a limited number of flops with asynchronous reset/preset (if any). Hence initial blocks and synchronous resets are the best options FPGA.
ASICs typically do not synthesize initial blocks. Initialization of flops is done with reset condition in synchronous logic. This is commonly an asynchronous reset but not required. In sort, synchronous or asynchronous reset for ASIC.
For both cases, to be synthesizable the initialization value needs to be deterministic and determined by constants. It cannot be derived on an input port or the current state of another register.
It is a good idea to follow these guidelines even if you plan to never synthesize. Otherwise is extra challenging to debug.

Related

How to implement sequential logic that exceeds a clock cycle?

I have a sequential Verilog code whereby at each increment of i, a different thing must happen.
For some of the i, there are no timing errors. However, for different values of i, I am getting timing errors (if omit these certain processes, then I get no timing errors).
I am wondering if there is a way in Verilog to allow combinational logic to take two clock cycles instead of one. Two clock cycles should be enough time to complete the processes, although I don't think I have seen anything like this before.
Thank you!
What you are looking for is called a 'multi cycle path'. A logic path (cone) that needs more then one clock cycle to complete.
You can define such a path using timing constraints but!!!
There are many pitfalls with using multi cycle paths.
I can't tell them all as that takes too long, but in your case there is an extra danger as you seem to be using the same path sometimes as single cycle, sometimes as multi-cycle.
If you define a path as multi-cycle the synthesis tool will optimise your logic to fit that multi-cycle path and then stop the optimisation. It is well possible that the timing no longer is optimised enough to complete in a 'single cycle'.
For example:your clock is 100MHz and you do not use multi-cycle path constraints. The synthesis tool will try to get the best timing and achieves 12ns delay. Your timing will fail.
Now you use multi-cycle path constraints specifying 2 cycles. The synthesis tool will try to get the best timing and at some point achieves 19ns delay. That is enough so it stops.
But now it is well possible that the timing no longer is optimised enough to complete in the 10ns for the cases where you have a 'single cycle'.

In ModelSim with verilog, can you reset the state of the simulation back to the start while continuing the simulation?

This is a very difficult question to word so I will describe what effect I desire.
Say if I have verilog code such as:
...
/*procedure 1 generating stimuli for module 1*/;
/*procedure 2 generating stimuli for module 1*/;
...
And module_thing has internal states that affect all future computation. Is there a command I can use such as 'reset_state' that will reset module_thing back to its start state?
So in verilog:
...
/*procedure 1 generating stimuli for module 1*/;
reset_state;
/*procedure 2 generating stimuli for module 1*/;
...
And in ModelSim, module_thing is appropriately 'cleared' of all values, before its second call, without the need to reset the simulation.
Thank you for reading.
You can't control time from inside a Verilog description, you can only wait for it to pass, or wait for a change in signal. You are thinking like software calling a function. That is not how hardware works. And you need to think about the difference between running a simulation of a hardware description written in Verilog, versus the script that you use to invoke the simulation. A simulation always starts at time 0 and moves forward. Time 0 is when all the initial and always blocks in your description start executing statements.
The script that runs the simulation can tell the tool to run for a certain amount of simulated time, stop, then restart at time 0. But that means all the initial and always blocks in your description start executing statements all over again.

In Verilog, whether always #(*) expects the actions to be completed in 1 clock period?

In Verilog, my peripherals are running at 100MHz = 10 nano seconds. In once always#(positive) block I was trying to do operations that exceeds 10 nano seconds. I rearranged the code so that the operations are performed now in an always#(*) block. Even now I have the same issue and my bitstream is not getting generated. So my question is why should always block should worry about the period ? as synchronization between clock and always#(*) block is not expected
While I cannot be certain that this is your problem without knowing more about your code and the synthesis results; it is possible you are running into a timing problem where the logic in your design cannot complete in a single 100MHz cycle.
When creating a sequential designs, one must always be aware that real logic has propagation delay. This means that the more logic is in between to registers (ie, that needs to be completed in a single clock cycle), the longer that logic will take in real time. Thus, what it seems you might be facing is that the amount of calculations you are trying to do in a single step takes longer than the clock period (minus the setup time of the registers that store the result).
Its also important to note that while changing your design from using a single always #(posedge) to an always #(*) will not result in any major changes in the synthesized result as the design you are describing is effectively the same (ie, a bunch of logic doing some calculations, followed by a set of registers to store the result). While simulating the design might be different, the hardware synthesized from the code will be very similar, thus the problem will remain.
In order to fix such timing problems, you can either break the logic into smaller pieces and pipeline it or you can change the design to bew iterative (taking multiple clock cycles). It is possible you might be able to change the logic in the design to convert long chains into tree structures or other things to try and break up the longest paths through the logic (thus decreasing overall propagation delay), but depending on the design, that might not be possible.

Should Xst 646 warning in Xilinx be ignored?

In my code, I've to use some registers which are used to store some values for making decision in code. They don't directly take values from input wire.
Now, I'm getting ...
Signal is assigned but never used. This unconnected signal will
be trimmed during the optimization process.
Should I ignore this warning? My simulation works correctly.
The short answer is: no, you shouldn't. The long answer is (as usually) "it depends".
Assigned signals that are detected as not being in use could mean that you forgot to connect a port of your module, or you mispelled a signal name. In these cases, it is likely that your design won't behave as expected.
On the other hand, there is a kind of construction that usually leads to this warning: the case in that a register is defined with N bits, although only some of them are actually used (for example, an 8 bit control register in a device, in which only bit 0 is used). In this case, the warning can be safely ignored. Your simulation will not be affected by this.
So just ask yourself whether that particular signal should be used (read) by any other part in your design or not.

Filling the Gaps on Verilog/System Verilog

I went over a few Verilog tutorials and reviewed the topics a couple times and a few questions have been lingering in my head from since the concepts were first introduced and if anyone could shed them light on them, that would be very helpful.
What's the purpose of strength on a net?
Often times in examples parameters exact names are used to also describe registers. For example:
module x (…,in1,…);
…
input in1;
reg [7:0] in1;
…
endmodule
Does this declare the input port as a type of data or are they separate? If the former is true, what other kinds of quantities can I do this with (integers, scalars, etc.)? If the latter is true which item am I referring to when I say “in1” inside the module?
Initial blocks at the beginning of a simulation all get executed in “parallel” but when you’re inside the block, the instructions are executed serially. Does the simulation tool you’re using determine what order the serially executed instructions are done in? For instance you have 2 initial blocks, do we execute all of one first, or jump back and forth?
4 .Why are initial values in simulation X? If Verilog’s job is to represent real life why doesn’t it have a pseudo random engine and pick the same random order of bits for all the values at the beginning? You run into a lot of issues with unique case statement warnings and it seems like a design flaw or at least an incongruity between system Verilog and Verilog.
Lets you have multiple drivers on a net and determine the value of the resulting signal; see 7.10 in the LRM
They're all the same in1 - very verbose. In V-2001 you can write a single input reg[7:0] in1 in the port list instead. You can do this for anything that you connect through a port.
Note that initial's are not guaranteed to be executed before always, and there is no guaranteed order of execution between any initial/always blocks in your design. In practice, the simulator chooses a block, and executes it until it reaches a suspend point (a timing control), at which point the sim schedules another initial or always, and executes that until it suspends, and so on.
This is essentially philosphy, but why would you want to assign initial random values to anything? This is basically what 'unknown' (X) means (or Z for nets). If everything is X or Z at the beginning of time, then you know that it's uninitialised and will remain so until you do something to it. If the tool gave everything initial random valid values you'd never know that.
In case of a contention strength helps to resolve to a known value. Last time I saw something like this in a design was it 10 years ago. And even then it was considered to be a bad design practice.
As EML says it.
No and No. The statements in any procedural block such as initial block are executed sequentially within the same time-slot. The initial blocks begin execution at time 0. The simulator executes all the statements in the order they appear inside the initial block as per the verilog event queue. The variables are updated as per the schedule dictated by the event queue. All of this is part of the standard (LRM 8.10). If you are not familiar with verilog event queue and the notion of time-slots and simulation time then Cliff Cumming's paper is a great reference. It doesn't matter if the simulator executes the statements from different initial blocks interleaved or any other way. The simulation time doesn't advance and the variables are only updated based on the event queue.
What is not standard is which initial block the simulator should begin with. This becomes important because this creates dependency on the simulator if variables are assigned in one initial block and used in the other procedural block within the same event queue. Cumming's paper referenced above explains this scenario very nicely.
It's not just about the unresolved state of the net. But also about starting the simulation from a predictable state. Therefore, randomly picking the resolved state of the inputs to the design would not provide the predictability in starting the simulator from the same point everytime. In addition to EML's suggestion, you may use the 2-state datatypes provided in SystemVerilog. Ofcourse, these are not synthesizable. Because, to accurately model the hardware you want the output state to be unknown if the inputs are unknown.

Resources