2017-10-18 39 views
-1

Dans mon cours de FPGA/Verilog, mon professeur a simplement passé en revue les fonctions. Il disait que dans les fonctions, vous écrivez le code procéduralement. Ensuite, lorsque vous voulez appeler la fonction, vous pouvez soit l'appeler dans un bloc always (c'est-à-dire procéduralement), soit l'appeler avec une instruction assign.Comment les fonctions sont-elles utilisées dans Verilog?

Cela ne me semble pas logique d'écrire une fonction avec un code de procédure, mais d'être appelée en continu.

Si quelqu'un a un aperçu de cette question (probablement) de base, il est très apprécié.

Cordialement

+0

Demandez à votre professeur pour l'expliquer. Obtenez votre argent. – toolic

Répondre

0

Il n'y a pas une telle chose comme continue dans Verilog, ou tout autre événement basée sur la simulation. Tout comportement est piloté par des événements discrets, c'est-à-dire qu'un signal change de valeur ou attend un temps discret. Une affectation continue dans Verilog est juste un moyen de définir une expression de sorte que, lorsqu'un opérande de l'expression RHS change, l'expression soit évaluée et son résultat est propagé à la cible LHS. Toute expression logique ou arithmétique peut inclure des appels de fonction.

0

Une fonction qui renvoie une valeur (fonction non-nulle) est utilisée dans verilog comme opérande d'une expression. Il encapsule une expression verilog, qui peut consister en plusieurs instructions dans la fonction. En tant que tel, il pourrait être utilisé dans n'importe quel endroit où l'expression pourrait être utilisée. Les blocs de procédure et les instructions d'assignation continue sont de tels endroits.

Le terme d'assignation continue est un terme historique et son but est d'amener des valeurs dans des réseaux (changer continuellement la valeur du réseau si la valeur d'expression d'entrée change). Donc, si une fonction est utilisée dans rhs, elle fournit simplement le calcul de la valeur en fonction de ses entrées.

donc, voici un exemple:

function automatic reg[3:0] sum (reg[3:0] a, reg[3:0] b); 
    sum = a + b; 
endfunction // b 

reg [3:0] r; 
wire [3:0] w; 

// use function in the procedural block 
always @* 
    r = sum(a, b); 

// use function in the continuous assignment 
assign w = sum(a,b); 
0

Il est à peu près exactement les mêmes que les blocs logiques combinatoires. Vous l'écrivez de cette façon, mais c'est synthétisé dans quelque chose de complètement différent. Considérez ce qui suit:

always @* begin 
    a = b + c; 
    d = b + a; 
end 

always @(posedge clk) begin 
    out <= d + in; 
end 

C'est exactement la même chose que:

function integer calc_d(integer b, integer c) begin 
    integer a; 
    a = b + c; 
    d = b + a; 
    calc_d = d; 
end 
endfunction 

always @(posedge clk) begin 
    out <= calc_c(b, c) + in; 
end