1. 程式人生 > >Verilog: How to avoid 'Redeclaration of ansi port'

Verilog: How to avoid 'Redeclaration of ansi port'

上次想要Vivado完整(無奈沒有板子)實現一遍操作流程,學習使用jou檔案來學習下工程模式的Tcl命令,於是就寫了一了小到不能再小的程式,一個二分頻的程式,就幾行程式碼,可即使如此簡單的一個程式,也出現了一些問題,這裡記錄下來,也許能幫到後來的人呢。

程式原來是這樣的:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/24 17:05:04
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module top(
    input ClkIn,
    input rst,
    output ClkOut
    );
    reg ClkOut;
    
[email protected]
(posedge ClkIn) begin if(rst) ClkOut = 1'b0; else ClkOut = ~ClkOut; end endmodule

注意,要使用復位,否則,模擬的話輸出會一直是未知的值。

這個程式看起來沒什麼問題,在我開始學習Verilog的時候,最正規的寫法也是這樣的,可是在接下來的操作,例如行為模擬的時候,出現如下錯誤提示:

也即,

redeclaration of ansi port ClkOut is not allowed [G:/Vivado_file/Two_frequency_division/Two_frequency_division.srcs/sources_1/new/top.v:28]

不允許重新宣告ansi埠ClkOut;

從上述提示也能看出,問題出在了top.v檔案中,也就是主程式中。模擬程式是沒有問題的,這裡也給出:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/24 17:08:59
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module tb(

    );
    reg clkin;
    reg rst;
    wire clkout;
    always
    begin
       #10 clkin = ~clkin;
    end
    
 
    initial
    begin
    clkin = 0;
    rst = 1;
    # 30
    rst = 0;
    end
    
       top u1(.ClkIn(clkin),.ClkOut(clkout),.rst(rst));
endmodule

問題出在了port:ClkOut的重新宣告,那主程式top.v中對ClkOut的宣告是分兩部分進行的:

module top(
    input ClkIn,
    input rst,
    output ClkOut
    );
    reg ClkOut;

這時,網際網路真是個好東西,查到了這個說明:https://electronics.stackexchange.com/questions/208984/verilog-how-to-avoid-redeclaration-of-ansi-port

於是,將上述宣告改成:

module top(
    input ClkIn,
    input rst,
    output reg ClkOut
    );

問題就解決了。

下面是上面連結中的大神給出的類似回答:

5

 

It's quite simple, you are redefining an ANSI port declaration.

    output [7:0] flags_timer_A //Defined here as an output wire
);
...

reg [7:0] flags_timer_A; //redefined as just a register

If you want to declare it as an output and a register in the ANSI style, you declare it simply as:

    output reg [7:0] flags_timer_A //Defined here as an output reg
);

上面忘了給出模擬波形:

前面那一塊紅色的輸出,也就是不確定值是為什麼呢?

從頂層程式碼中我們可以看到,我們使用的是同步復位,所以要等到時鐘上升沿的時候,才會判斷是否復位了,至於復位之前的輸出,誰知道是什麼呢?所以是未知值,不定值。