Newbie Question: Division Result wrong when using input longint

In my main/top module I instantiate the following:

longint baudRate = 9600;

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

module UART_BaudRate_generator( Clk, Tick, BaudRate );

input           Clk                 ; // Clock input
input longint   BaudRate            ; // Bits per second
output          Tick                ; // Each "BaudRate" pulses we create a tick pulse

longint         BaudRateClocks;       // Number of FPGA clock cycles requires for 1 baud period
longint         freqFPGA;  
longint         currClockCount;       // Register used to count

initial 
begin
  Tick = 0;
  currClockCount = 0;
	
  freqFPGA = 50000000;   // 50MHz
	
  //BaudRateClocks = 50000000 / 9600;       // Works OK
  //BaudRateClocks = 50000000 / BaudRate;   // FAILS
  //BaudRateClocks = freqFPGA / 9600;       // Works OK
  BaudRateClocks = freqFPGA / BaudRate;     // FAILS
end

always @(posedge Clk)
begin
  currClockCount ++;
  if(currClockCount >= BaudRateClocks) 
  begin
    Tick = ! Tick;
    currClockCount = 0;
  end
  else 
  begin
    currClockCount ++;
  end
end

endmodule

I try to calculate 50000000 / 9600 within the module and I don’t get the correct value. If I try a literal value of 9600 within the module then I do get the correct result. What am I doing wrong? I’m assuming that the initial block is called when the module is instantiated.

In reply to SparkyNZ:
BTW, when asking questions, it always helps when you explain the correct value you expect versus what you were actually seeing.

I’m guessing you are seeing a 0 result, because BaudRate is still 0 at the time the initial block gets executed. That’s because you have a race condition between the initial block and the propagation of the input port. If you don’t expect BaudRate to change at any time, then you probably should declare it as a parameter instead of an input port.

module UART_BaudRate_generator #(longint BaudRate) ( 
   input           Clk                 , // Clock input
   output bit      Tick                 // Each "BaudRate" pulses we create a tick pulse
);
localparam longint freqFPGA = 50000000;                 // 50MHz;  
localparam longint BaudRateClocks = freqFPGA/BaudRate; // Number of FPGA clock cycles requires for 1 baud period

longint currClockCount;       // Register used to count
initial 
begin
  Tick = 0;
  currClockCount = 0;
end
always @(posedge Clk)
begin
  currClockCount ++;
  if(currClockCount >= BaudRateClocks) 
  begin
    Tick = ! Tick;
    currClockCount = 0;
  end
  else 
  begin
    currClockCount ++;
  end
end
 
endmodule

parameter longint baudRate = 9600;
 
UART_BaudRate_generator #(.BaudRate(baudRate))
     BaudGen1(
    .Clk( clk ),
    .Tick( baudTick )
    );

In reply to dave_59:

Thanks for that Dave. As you may have guessed I am from a software developer background. You’ve certainly given me a few points to read up on. I didn’t realise you could pass parameters as such. Definitely in this case I would have been aiming for passing in a constant value.

For me it’s quite hard to seperate or think about applying solutions in an asynchronous manner. I’m quite happy doing so on a breadboard etc but when it comes to FPGA programming it’s a bit of a challenge. :) I still don’t feel as though I have found the right learning resource/reference for me yet. I only switched to SystemVerilog a few days ago upon discovering that I could use better functions for handling strings and the likes - I’m trying to set up my own serial terminal interface for debugging.

I wondered whether or not I should have tried all of this out with modelsim so I could have witnessed debug and see what my actual values were but I kept tinkering with the actual hardware and scope until I couldn’t take any more :-)

Anyway thanks again for getting me over this hurdle!

In reply to SparkyNZ:

I had to massage things around a little but this seems to work now:

Calling code:

parameter longint baudRate = 9600;

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

Implementation:

module UART_BaudRate_generator #(parameter longint BaudRate=19200) // Bits per second
(
    input  Clk,  
    output Tick  // Each "BaudRate" pulses we create a tick pulse
    
);

localparam longint freqFPGA       = 50000000;             // 50MHz
localparam longint BaudRateClocks = freqFPGA / BaudRate;  // Number of FPGA clock cycles requires for 1 baud period

etc..

I just added the 19200 default for the parameter to make sure it was using the 9600 value passed in. My scope is now happy!