我对Verilog和FPGA开发还很陌生,并注意到在仿真和综合之间需要注意各种差异。我正在使用Altera DE1板和Quartus II软件。
这是我无法弄清楚的事情。我有以下代码来实例化一个模块:
reg [9:0] x0;
initial begin
x0 = 10'd200;
end
linepro linedrawer1
(.CLOCK(I_CLK),
.RST(reset_drawer),
.done(drawer_done),
.x0(x0),
.y0(10'd200),
.x1(10'd500),
.y1(10'd100),
.outx(x),
.outy(y));
正如您所看到的,我正在将初始化的reg挂接到我的linepro模块的端口。此代码似乎在模拟下工作,但未正确初始化fpga板上的x0。
为了使这段代码正常工作,并正确实例化linepro模块,我做了以下几点修改:
reg [9:0] x0reg;
wire [9:0] x0;
assign x0=x0reg;
initial begin
x0reg = 10'd200;
end
linepro linedrawer1
(.CLOCK(I_CLK),
.RST(reset_drawer),
.done(drawer_done),
.x0(x0),
.y0(10'd200),
.x1(10'd500),
.y1(10'd100),
.outx(x),
.outy(y));
在此示例中,我将reg分配给导线并将导线挂接到linepro模块。
使用reg直接实例化模块和将reg分配给线路并使用该线路实例化模块之间有什么区别?一种方法可能起作用的原因是什么?另一种方法可能没有?
提前感谢您的任何帮助。
答案 0 :(得分:2)
当您编写综合RTL时,您应该记住您实际尝试实现的逻辑电路。虽然通常初始模块不可合成,但某些FPGA供应商允许您为触发器,锁存器和存储器等存储器元件指定上电状态。在这种情况下,看起来x0不是任何东西 - 它只是一个常量应用于linepro模块的一个输入。在这种情况下,您可能只需在端口列表中指定该值,就像使用y0,y1和x1端口一样,这是完全可合成的,而不是使用初始块。
答案 1 :(得分:0)
Quartus确实使用“ initial”语句支持寄存器和存储器的初始化。我怀疑这里的问题是您实际上从未实现过寄存器。
我想知道这是否行得通
reg [9:0] x0reg;
initial x0reg = 10'd200;
always @(posedge clk) begin
x0reg <= x0reg;
end
这应该推断出一个x0reg寄存器,并在配置FPGA时将其初始化为0x200。另外,如果您只想让reg表现得像电线一样:
reg [9:0] x0reg;
always_comb x0_reg = 10'd200;
以上应该可以。请注意,always @*
在那种情况下不会起作用,因为always @*
和always_comb
之间的主要区别之一是always_comb
块在在仿真开始时,always @*
块仅在输入发生更改时触发(在零时可能不会发生)。 (通常,您应该始终使用always_comb
,而永远不要使用always @*
。)