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
);
上面忘了給出模擬波形:
前面那一塊紅色的輸出,也就是不確定值是為什麼呢?
從頂層程式碼中我們可以看到,我們使用的是同步復位,所以要等到時鐘上升沿的時候,才會判斷是否復位了,至於復位之前的輸出,誰知道是什麼呢?所以是未知值,不定值。