上次想要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;always@(posedge ClkIn)beginif(rst) ClkOut = 1'b0;else ClkOut = ~ClkOut;endendmodule
注意,要使用复位,否则,仿真的话输出会一直是未知的值。
这个程序看起来没什么问题,在我开始学习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;alwaysbegin#10 clkin = ~clkin;endinitialbeginclkin = 0;rst = 1;# 30rst = 0;endtop 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
);
上面忘了给出仿真波形:
前面那一块红色的输出,也就是不确定值是为什么呢?
从顶层代码中我们可以看到,我们使用的是同步复位,所以要等到时钟上升沿的时候,才会判断是否复位了,至于复位之前的输出,谁知道是什么呢?所以是未知值,不定值。