本文介绍了获取“无效模块实例化"在我的 FIR Verilog 代码中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码是一个顺序结构,8 个恒定抽头,8 位 FIR.我使用内存来保存所有输入*分接头,但在尝试保存这些乘法时我不断出错.

My code is a sequential structure, 8 constant taps, 8 bit FIR. I used a memory to save all the input*taps, but I keep getting and error while trying to save these multiplications.

我在 Modelsim 上编译它并得到语法错误".之后,我尝试了 iverilog 并得到了语法错误"和错误:模块实例化无效".我觉得我遗漏了一些非常明显但无法解决的问题.

I compiled it on Modelsim and got "syntax error". After, I tried iverilog and got "syntax error" and "error: Invalid module instantiation". I feel like I'm missing something really obvious but couldn't solve it.

代码如下:

/*  Código de um filtro FIR 8 taps, 8 bits
Aluno: Rafael Menezes
Start date: 19/07/2017

Modelo original - Sequencial ALTERNATIVO por reg+load
v1.5

BUG REPORT:
    - Problema com a memória das multiplicações (linha 54);

NOTES:
    - Incrementador do sel é feito por always (linha 59);
    - Necessita, também, fazer o xor pro load (?);
*/

//código do fir
module fir(x,clk,rst,y);
input signed [8:0]x;                        //entrada do fir
input clk,rst;                              //clock e reset
output signed [16:0]y;                      //saída do fir
reg signed [16:0] m[0:7];                   //variáveis auxiliares para as multiplicações
wire signed [8:0]x1,x2,x3,x4,x5,x6,x7;      //variáveis auxiliares para os atrasos
wire signed [8:0]x_aux;                     //variável auxiliar para o atraso selecionado pelo mux
wire signed [8:0]h_aux;                     //variável auxiliar para o tap selecionado pelo mux
reg         [2:0]sel;                       //variável responsável pelo select do mux
parameter n=8;                              //parâmetro do loop das multiplicações

// valores pré-definidos dos taps
parameter signed h0=-4'd1;
parameter signed h1=4'd7;
parameter signed h2=-4'd2;
parameter signed h3=4'd5;
parameter signed h4=-4'd5;
parameter signed h5=4'd3;
parameter signed h6=4'd1;
parameter signed h7=4'd4;

    //atrasos
    ffd u1(clk,rst,x,x1);   //x[n-1]
    ffd u2(clk,rst,x1,x2);  //x[n-2]
    ffd u3(clk,rst,x2,x3);  //x[n-3]
    ffd u4(clk,rst,x3,x4);  //x[n-4]
    ffd u5(clk,rst,x4,x5);  //x[n-5]
    ffd u6(clk,rst,x5,x6);  //x[n-6]
    ffd u7(clk,rst,x6,x7);  //x[n-7]

genvar i;
generate
    for (i=0; i<n; i=i+1) begin: mux
    mux81 mux1(.clk(clk),.sel(sel),.in1(x),.in2(x1),.in3(x2),.in4(x3),
                    .in5(x4),.in6(x5),.in7(x6),.in8(x7),.out(x_aux));           //mux que seleciona as entradas
    mux81 mux2(.clk(clk),.sel(sel),.in1(h0),.in2(h1),.in3(h2),.in4(h3),
                    .in5(h4),.in6(h5),.in7(h6),.in8(h7),.out(h_aux));           //mux que seleiona os taps
    m[i]=x_aux*h_aux;       // THE ERROR IS RIGHT HERE!
    end
endgenerate

//rotina que incrementa o select a cada pulso de clock
always @(posedge clk) begin
    if (sel==3'b111) begin
         sel <= 3'b000;
    end else begin
         sel <= sel + 3'b001;
    end
end

    assign y=m[0]+m[1]+m[2]+m[3]+m[4]+m[5]+m[6]+m[7];

endmodule


//código do flip flop d que será usado como o integrador (atraso)
module ffd(clk,rst,in,out);
input clk,rst;
input signed [8:0]in;
output signed [8:0]out;
reg signed [8:0]out;

always @ (posedge clk) begin            //sembre na borda de subida verifica se o rst está ligado
    if(rst==1) begin                    //se não estiver ligado, atribui a entrada para a saída
        out<=0;
    end else begin
        out<=in;
    end
end

endmodule

//código mux para selecionar os taps e as entradas
module mux81(clk,sel,rst,in1,in2,in3,in4,in5,in6,in7,in8,out);
input signed [8:0]in1,in2,in3,in4,in5,in6,in7,in8;
input [2:0]sel;
input clk,rst;
output signed [8:0]out;
reg signed [8:0]out;

always @ (posedge clk or sel) begin
    if (rst==1) begin
        out<=0;
    end else if (sel==3'd0) begin
        out<=in1;
    end else if (sel==3'd1) begin
        out<=in2;
    end else if (sel==3'd2) begin
        out<=in3;
    end else if (sel==3'd3) begin
        out<=in4;
    end else if (sel==3'd4) begin
        out<=in5;
    end else if (sel==3'd5) begin
        out<=in6;
    end else if (sel==3'd6) begin
        out<=in7;
    end else if (sel==3'd7) begin
        out<=in8;
    end
end

endmodule

推荐答案

Verilog 模块在语法上可能包含声明、过程块、连续分配和模块实例化.像这样的表达式 m[i]=x_aux*h_aux; 单独存在会混淆 verilog 编译器.它在 'generate' 块内使用的事实不会改变任何东西,因为后者不代表这样的范围,而只是内联其 ins 内部.

Verilog module syntactically might contain declarations, procedural blocks, continuous asisgnments, and module instantiations. The expression like this m[i]=x_aux*h_aux; standing alone confuses the verilog compiler. The fact that it is used inside the 'generate' block does not change anything because the latter does not represent such a scope and only in-lines its ins internals.

因此,我假设 OP 想要为寄存器 'm[i]' 分配一个值(其中 [i] 是生成的索引).在 verilog 中,这可以在程序块中完成(在这种情况下总是块).因此,考虑到 verilog v2k 语法,正确使用是:

So, I assume that OP wanted to assign a value to the register 'm[i]' (where [i] is a generated index). In verilog this can be done in an procedural block (always block in such a case). So, the correct use, taking in account verilog v2k syntax is:

always @*
    m[i]=x_aux*h_aux;

在系统 verilog 中,我建议改用它:

in system verilog I recommend to use this instead:

always_comb
    m[i]=x_aux*h_aux;

这篇关于获取“无效模块实例化"在我的 FIR Verilog 代码中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-12 09:38