Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16595 Discussions

Verilog | Instantiating a varied parameter

Altera_Forum
Honored Contributor II
3,647 Views

Hi, 

 

I'm working on building an SPI core using verilog, and am running into some problems. 

My slave device is an ADC with 8 analog channels, of which the user can choose to read from either a single channel or multiple ones within the same command. 

 

The structure of the command is as follow: 

[WR bit - if true there is a write operation in current cycle] [repeat mode - can ignore this and assume logic low] [8 bits for channel selection] [rest are don't care bits]. 

 

Right now, my program works for a single channel in write mode, and I was looking into allowing the use of multiple channels per command using a sub-module for counting the number of 1's inside an input data, thus knowing for how many consecutive cycles to activate my SPI core (i.e. "telling" the MASTER to be prepared for 'X' number of results to arrive back from the SLAVE). 

 

What I wish to do is the following: 

 

AD7298_1# ([number of 1's calculated]) U_6( 

.clr (clr), 

.clk (clk), 

... 

); 

 

[Inside I assign the parameter value for activating SYNCn for 'X' number of cycles]. 

 

ModelSim compiler yields the following error: an expression for a parameter actual for the module instance ('u_6') is not constant. parameter expressions must be constant. 

 

Does anyone here knows of a way to get around this? 

 

Thank you for your time, 

Refael. 

 

P.S. 

 

I am using an Analog Devices ADC, with P/N: AD7298-1.
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
1,822 Views

You left out the most important part. The [NUMBER OF 1'S CALCULATED] is where the problem is. Please post that. 

 

Keep in mind that parameter values must be known at compile time. You can do calculations with them, but any inputs must be constants or other parameters. They cannot be variables, registers, wires etc. Verilog isn't like software languages. The hardware is created when the FPGA image is built and in general cannot be changed at runtime.
0 Kudos
Altera_Forum
Honored Contributor II
1,822 Views

Hi Galfonz, 

 

Thank you for your reply. 

What do you mean by "You can do calculations with them"? 

I saw that in System Verilog one can use something which is called 'parameter type' - is it related to my question? 

Anyways, here is my code for calculating 1's in an input vector: 

 

`resetall 

`timescale 1ns/10ps 

`define CCT 10 

 

module ones_counter  

// Port Declarations 

(input wire aclr_n,  

input wire clk,  

input wire [15:0] data, 

input wire sync_n, 

input wire fin_read, 

output reg [2:0] ones_num 

); 

 

// Internal Declarations 

wire equ; 

reg [7:0] data_shift; 

reg [2:0] ones_cnt; 

 

/* --------------------------------------------------------------------------- 

****************** counting number of ones in a vector *********************** 

--------------------------------------------------------------------------- */ 

 

always @ (posedge clk, negedge aclr_n) 

begin 

if (!aclr_n) 

data_shift <= 8'b0; 

else 

if (sync_n) 

data_shift <= data[13:6]; 

else 

data_shift <= data_shift << 1; 

end 

 

assign equ = (data_shift[7] ^ 1'b0) & (!sync_n); 

 

always @ (posedge clk, negedge aclr_n) 

begin 

if (!aclr_n) 

ones_cnt <= 3'b0; 

else 

if (equ && data[15]) 

ones_cnt <= ones_cnt + 1'b1; 

else 

if (fin_read) 

ones_cnt <= 3'b0; 

end 

 

always @ (posedge clk, aclr_n) 

begin 

if (!aclr_n) 

ones_num <= 3'b0; 

else 

if (data_shift[7:0] == 8'b0) 

ones_num <= ones_cnt; 

else 

ones_num <= 3'b0; 

end 

 

endmodule 

 

I wish to instantiate ones_num register value to my main code. 

 

- refael.
0 Kudos
Altera_Forum
Honored Contributor II
1,822 Views

 

--- Quote Start ---  

You left out the most important part. The [NUMBER OF 1'S CALCULATED] is where the problem is. Please post that. 

 

Keep in mind that parameter values must be known at compile time. You can do calculations with them, but any inputs must be constants or other parameters. They cannot be variables, registers, wires etc. Verilog isn't like software languages. The hardware is created when the FPGA image is built and in general cannot be changed at runtime. 

--- Quote End ---  

 

 

Hi Galfonz, 

 

 

Thank you for your reply. 

What do you mean by "You can do calculations with them"? 

I saw that in System Verilog, one can use something which is called 'Parameter Type' - can it do what I want? 

 

 

Here's my code for calculating number of 1's in an input data: 

 

 

`resetall 

`timescale 1ns/10ps 

`define cct 10 

 

 

module ones_counter  

// port declarations 

(input wire aclr_n,  

input wire clk,  

input wire [15:0] data, 

input wire sync_n, 

input wire fin_read, 

output reg [2:0] ones_num 

); 

 

 

// internal declarations 

wire equ; 

reg [7:0] data_shift; 

reg [2:0] ones_cnt; 

// local declarations 

 

 

// internal signal declarations 

 

 

/* --------------------------------------------------------------------------- 

****************** counting number of ones in a vector *********************** 

--------------------------------------------------------------------------- */ 

 

 

always @ (posedge clk, negedge aclr_n) 

begin 

if (!aclr_n) 

data_shift <= 8'b0; 

else 

if (sync_n) 

data_shift <= data[13:6]; 

else 

data_shift <= data_shift << 1; 

end 

 

assign equ = (data_shift[7] ^ 1'b0) & (!sync_n); 

 

 

always @ (posedge clk, negedge aclr_n) 

begin 

if (!aclr_n) 

ones_cnt <= 3'b0; 

else 

if (equ && data[15]) 

ones_cnt <= ones_cnt + 1'b1; 

else 

if (fin_read) 

ones_cnt <= 3'b0; 

end 

 

always @ (posedge clk, aclr_n) 

begin 

if (!aclr_n) 

ones_num <= 3'b0; 

else 

if (data_shift[7:0] == 8'b0) 

ones_num <= ones_cnt; 

else 

ones_num <= 3'b0; 

end 

 

 

endmodule 

 

 

ones_num register holds the final result at the end, and I wish to instantiate this value to my main code. 

 

 

- Refael.
0 Kudos
Altera_Forum
Honored Contributor II
1,822 Views

Parameters are constants that are must be known when Quartus is run. Parameters are used in your code that defines what the circuit looks like. This is similar to how# define works in C/C++. What you have calculates the number of 1s and then expects the circuit to change at run time based on that. You could use a parameter for something like the max number of 1s, or the width of signals. You cannot use them for things that are calculated when the circuit is running.

0 Kudos
Altera_Forum
Honored Contributor II
1,822 Views

 

--- Quote Start ---  

Parameters are constants that are must be known when Quartus is run. Parameters are used in your code that defines what the circuit looks like. This is similar to how# define works in C/C++. What you have calculates the number of 1s and then expects the circuit to change at run time based on that. You could use a parameter for something like the max number of 1s, or the width of signals. You cannot use them for things that are calculated when the circuit is running. 

--- Quote End ---  

 

 

Hi Galfonz, 

 

I realize that HW (i.e. Flip-Flops) cannot be created during run rime. 

Can you suggest than of a way to get around this, when you know that upon a user request the program needs to be executed 'X' number of times? 

 

BTW, is there a sub-thread where I can share my piece of code and receive feedback. 

 

Thank you for your time, 

Refael.
0 Kudos
Altera_Forum
Honored Contributor II
1,822 Views

I'd suggest not counting the number of ones. To have all channels active at once, make several instantiations of your controller. To use the same hardware to operate several channels, use mux/demux.

0 Kudos
Reply