我正在尝试将整数值传递给模块,但IF
语句不适用于该参数。它会引发以下错误。我是 Verilog 的新手,所以我不知道如何使这项工作。
Error (10200): Verilog HDL Conditional Statement error at clock_divider.v(17):
cannot match operand(s) in the condition to the corresponding edges in the enclosing
event control of the always construct
clock_divider.v模块
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always @ (posedge clk or negedge rst_n)
begin
if(clockHandler == 0)
begin div_helper = DIV_CONST;
end
else
begin div_helper = DIV_CONST_faster;
end
if (!rst_n)
begin div <= 0;
en <= 0;
end
else
begin
if (div == div_helper)
begin div <= 0;
en <= 1;
end
else
begin div <= div + 1;
en <= 0;
end
end
end
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
clk_o <= 1'b0;
end
else if (en)
clk_o <= ~clk_o;
end
endmodule
main.v模块
reg clockHandler = 1;
// 7-seg display mux
always @ (*)
begin
case (SW[2:0])
3'b000: hexdata <= 16'h0188;
3'b001: hexdata <= register_A ;
3'b010: hexdata <= program_counter ;
3'b011: hexdata <= instruction_register ;
3'b100: hexdata <= memory_data_register_out ;
3'b111: hexdata <= out;
default: hexdata <= 16'h0188;
endcase
if(SW[8] == 1)
begin
clockHandler = 1;
end
else
begin
clockHandler = 0;
end
end
HexDigit d0(HEX0,hexdata[3:0]);
HexDigit d1(HEX1,hexdata[7:4]);
HexDigit d2(HEX2,hexdata[11:8]);
HexDigit d3(HEX3,hexdata[15:12]);
clock_divider clk1Hzfrom50MHz (
clockHandler,
CLOCK_50,
KEY[3],
clk_1Hz
);
答案 0 :(得分:4)
我的理解是,如果您使用异步重置,则verilog始终阻止的第一个语句必须是if(reset)
项。
所以翻牌结构应该总是这样:
always @ (posedge clk or negedge rst_n) begin
if(~rst_n) begin
...reset statements...
end else begin
...all other statements...
end
end
因此,对于您的情况,您应该在if(clockHandler==0)
语句中移动else
块,因为它与重置执行无关。更好的方法是将它移动到一个单独的组合总是阻塞,因为在一个总阻塞内混合阻塞和非阻塞语句通常不是一个好主意,除非你真的知道你在做什么。我认为你的情况很好。
答案 1 :(得分:0)
要添加到Tim的答案 - 原始代码(无论如何,第17行)都是有效的Verilog。
它的含义是“只要clk
上升到rst_n
或clockHandler
的下降沿,检查clockHandler
并执行某些操作”(由方式,摆脱开始/结束;他们是冗余和冗长的)。当你想在真实硬件中实现它时,问题出现了,因此错误消息可能来自合成器,它需要的不仅仅是有效的Verilog。合成器怀疑它必须构建某种类型的同步元素,但是它不能(或者不会,精确地)处理在两者的边缘检查clk
的情况。 / em> rst_n
和{{1}}。遵循综合模板的规则,您将不会遇到此问题。
答案 2 :(得分:0)
这是编译错误还是合成错误?我使用相同的代码来查看它是否编译正常,我得到错误..此外,建议在同步块内使用“&lt; =”而不是“=”
答案 3 :(得分:0)
你使用相同的翻牌构造来做两件事。在代码中线性地导致状态的滑动。如果状态依赖于该时钟或重置,我总是将所有内容放在一个构造内,否则您需要额外的步骤来确保多个信号不会尝试改变您的状态。
当涉及翻牌结构时,你也不需要开头/结尾,Verilog知道如何为你处理。我相信Verilog虽然可以,但我通常不这样做。在块中使用单个语句时,也不必使用它。
所以你的第一个模块看起来像这样(如果我错过了一个块,请告诉我):
clock_divider.v模块(已编辑)
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div <= 0;
en <= 0;
clk_o <= 1'b0;
end
else if(en)
begin
clk_o <= ~ clk_o;
if(clockHandler == 0)
begin
div_helper = DIV_CONST;
end
else
begin
div_helper = DIV_CONST_faster;
end
else
begin
if (div == div_helper)
begin
div <= 0;
en <= 1;
end
end
else
begin
div <= div + 1;
en <= 0;
end
end
end
end module
如果clk_o不打算同时处理那些其他操作,那么你可以用一般的'else'语句将其他所有内容分开。请确保将第二个构造嵌套为if语句以检查您的状态。
还记得像Tim提到的那样将@(posedge clk或negedge rst_n)添加到你的main.v模块中。