1

I'm working on a Verilog module where I want to add a clock that is able to be changed through frequency values. I tried referencing two variables as integers, assigned the first variable [frequency] a number that corresponds to the frequency value (in MHz), and I used that variable's name to do math operations to get the value of the second variable [clk_period]. It doesn't let me though.

I have the following code:

    integer frequency = 100;                      //in MHz
    integer clk_period = (1/(frequency*1e6))*1e9; // 1/freq = clk_prd (in seconds) * 10^9 (in nanoseconds)

and this is the error I get:

error: A reference to a wire or reg (`frequency') is not allowed in a constant expression.

I haven't referenced 'frequency' as a wire or a reg, rather as integer. Is this feature (using an integer to assign a value to another integer) unavailable, or am I doing something wrong here?

toolic
  • 57,801
  • 17
  • 75
  • 117
teach_me
  • 13
  • 4

2 Answers2

0

The iverilog simulator is telling you that it does not support declaring and assigning those types in the same statement.

You can separate them into two statements:

integer clk_period;
initial clk_period = (1/(frequency*1e6))*1e9; // 1/freq = clk_prd (in seconds) * 10^9 (in nanoseconds)

This works on EDA Playground

toolic
  • 57,801
  • 17
  • 75
  • 117
0

Which tool produces the error message. I tried it in eda playground and it worked with all commercial simulators.

Note, that initialization of vars like that is not synthesizable. There are fpga hooks that allow it but those are limited. So, is your message produced by a synthesis tool?

Potentially you can make your 'frequency' into a constant. This should theoretically solve the 'constant expression' issue.

  parameter frequency = 100;
  integer clk_period = (1/(frequency*1e6))*1e9;

If you use it for testbench, just put everything inside an initial block. This might work for fpgas.

  integer frequency; // or parameter frequency = 100;
  integer clk_period;

  initial begin
     frequency = 100; // do not need wit parameter
     clk_period = (1/(frequency*1e6))*1e9;
  end

or if you want to make it really synthesizable, something like the following will work.

parameter frequence = 100;
...
always @(posedge clk)
   if (reset)
      clk_period <= (1/(frequency*1e6))*1e9;
Serge
  • 11,616
  • 3
  • 18
  • 28