Newbie Question: Understanding initial block and module instantion

I’m confused about program/module startup.

module SystemVerilogTest1( input logic clk, output logic led2 );

logic baudTick;

initial 
begin
  baudTick = 0;
end

parameter longint baudRate = 9600;

UART_BaudRate_generator #(baudRate) BaudGen1(
    .Clk( clk ),
    .Tick( baudTick )
    );

When I try to compile this in Altera ModelSim it gives me the following errors:

# ** Error: (vsim-3838) E:/FPGA Cylone Projects/UART_BaudRate_generator.sv(23): Variable '/SystemVerilogTest1/baudTick' written by continuous and procedural assignments. See E:/FPGA Cylone Projects/SystemVerilogTest1.sv(13). 
#         Region: /SystemVerilogTest1/BaudGen1

I’m guessing this is because there could be a race condition between the initial block and the BaudGen1 instantiation. BaudGen1 must be a “continuous” module which is continously modifying baudTick which could clash with the initial block?

How would I go about cleaning up the initialisation so that everything happens in sequence? Is it not possible to instantiate BaudGen1 as part of the initial block?

In C++ I’d be thinking that the BaudGen1 instantion would take place first and the initial block would be the equivalent of a main() function but I guess not.

The other question I could ask is “How should I be initialising baudTick?” What I want is for baudTick to be initialised first, and then BaudGen1 to be instantiated.

In reply to SparkyNZ:

I think you need to go and review a basic Verilog and SystemVerilog tutorial, what you have is a mix of continuous and non-continuous assignment (as the tool points out), I’m assuming the port Tick of your module UART_BaudRate_generator is an output assigned using the ‘assign’ keyword which is a continous assignment (occurs every time an event is evaluated, i.e input values changing), so this clashes with your initialisation in the code shown which is a procedural assignment, also keep in mind you are describing hardware and several things occur concurrently, in your case if this port is an output why would you like to initialise it outside of the module who is responsible of generating it?

The LRM https://ieeexplore.ieee.org/document/8299595 section 6.5 states the following:
“…An assignment where the left-hand side contains a slice is treated as a single assignment to the entire slice.
Thus, a structure or array can have one element assigned procedurally and another element assigned
continuously. And elements of a structure or array can be assigned with multiple continuous assignments,
provided that each element is covered by no more than a single continuous assignment…”

Regarding to the main() and initial part, initial blocks are threads that start execution at time 0, I’d suggest to go thru a tutorial (VLSI Design - Verilog Introduction | Tutorialspoint) always refer to the LRM keeping in mind that not all tool vendors support the latest version in all their tool versions, but for that you need to contact your vendor directly.

Anyways I hope this helps.and probably someone will give a more concise answer.
-R

In reply to rgarcia07:

I’ll just add that it doesn’t matter how
Tick
gets its value inside the module
UART_BaudRate_generator
. What matters is that its a module output port, and that behaves as a continuous assignment to
baudTick
.

There should be no need to initialize
baudTick
in your testbench because you initialized it in the lower level module.

In reply to dave_59:

In reply to rgarcia07:
I’ll just add that it doesn’t matter how
Tick
gets its value inside the module
UART_BaudRate_generator
. What matters is that its a module output port, and that behaves as a continuous assignment to
baudTick
.
There should be no need to initialize
baudTick
in your testbench because you initialized it in the lower level module.

I think you have hit the nail on the head Dave. I should initialise the Tick output within an intial block of the UART_BaudRate_generator module. That makes sense to me now. Thanks again.

In reply to rgarcia07:

Thanks for the reply. I do keep referring to tutorials but it is hard to get into the mindset. I’ll do some more reading all the same. I wasn’t using an assign statement - I am tending to avoiding continuous statements unless I want to wire up an output to another pin so it can be monitored by my scope.

Actually I will accept your answer as the solution because you did point out that I shouldn’t be initialising something outside of the module that drives the output. I thought Dave had said that. Either way - thanks both of you. :-)