J'écris un projet avec Verilog et je veux utiliser parameter
pour définir un paramètre dans mon module. Mais quand je lis dans du code source, localparam
est parfois utilisé à la place de parameter
.
Quelle différence entre eux?
Généralement, l'idée derrière le localparam
(ajouté à la norme Verilog-2001) est de protéger la valeur de localparam
d'une redéfinition accidentelle ou incorrecte par un utilisateur final (contrairement à un parameter
value, cette valeur ne peut pas être modifiée par la redéfinition des paramètres ou par une instruction defparam
).
Basé sur IEEE 1364-2005 (ch. 4.10.2):
Les paramètres locaux Verilog HDL sont identiques aux paramètres, sauf qu'ils ne peuvent pas être directement modifiés par les instructions defparam ou les affectations de valeurs de paramètre d'instance de module . Les paramètres locaux peuvent recevoir des expressions constantes contenant des paramètres, qui peuvent être modifiées avec des instructions defparam ou des affectations de valeurs de paramètres d'instance de module.
De plus, dans SystemVerilog ( IEEE 1800-2012 (ch. 6.20.4)):
Contrairement aux paramètres non locaux, les paramètres locaux peuvent être déclarés dans un bloc de génération, un package, un corps de classe ou une étendue d'unité de compilation. Dans ces contextes, le mot-clé de paramètre doit être un synonyme du mot-clé localparam.
Les paramètres locaux peuvent être déclarés dans un paramètre_port_list d'un module. Toute déclaration de paramètre apparaissant dans une telle liste entre un mot-clé localparam et le mot-clé de paramètre suivant (ou la fin de la liste, s'il n'y a pas de mot-clé de paramètre suivant) doit être un paramètre local. Toute autre déclaration de paramètre dans une telle liste doit être un paramètre non local qui peut être remplacé.
Si vous voulez en savoir plus sur ce sujet, je vous recommande l'article de Clifford E. Cummings " Nouvelles techniques Verilog-2001 pour créer des modèles paramétrés (ou vers le bas avec` définir et mort d'un defparam!) ".
Exemple minimal
Voici un exemple de ce que Qiu a mentionné.
Dans une RAM, la taille de la mémoire est fonction des tailles de mot et d'adresse.
Donc, si le module parent spécifie Word et la taille de l'adresse, il ne devrait pas non plus pouvoir spécifier la taille de la mémoire.
module myram #(
parameter Word_SIZE = 1,
parameter ADDR_SIZE = 1
) (
input wire [ADDR_SIZE-1:0] addr,
inout wire [Word_SIZE-1:0] data,
// ...
);
localparam MEM_SIZE = Word_SIZE * (1 << ADDR_SIZE);
// Use MEM_SIZE several times in block.
...
Et sur le module parent, c'est bien:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.Word_SIZE(2)
) top (
/* wires */
)
mais ceci devrait être une erreur:
module myram_tb;
myram #(
.ADDR_SIZE(2),
.Word_SIZE(2),
.MEM_SIZE(2)
) top (
/* wires */
)
iverilog
n'échoue pas, et je pense que c'est un bug: https://github.com/steveicarus/iverilog/issues/157
Incisive donne une erreur comme prévu.