我试图围绕组合和行为逻辑的混合。我有一个带有4个LED和66 MHz时钟输入的小型FPGA。这个想法是让它们中的两个发光(一个上升,一个下降),另外两个闪烁。所以我想出了以下代码:
module ledflash(input wire CLK,
input wire USER_RESET,
output wire LED[3:0]);
reg [26:0] cnt;
reg [4:0] pwm;
wire led_enable = ~USER_RESET;
always @(posedge CLK)
begin
if (led_enable)
begin
cnt <= cnt + 1;
pwm <= pwm[3:0] + (cnt[26] ? cnt[25:22] : ~cnt[25:22]);
end
else
begin
cnt <= 0;
pwm <= 0;
end
end
assign LED[0] = led_enable ? (cnt[26] ? pwm[4] : ~pwm[4]) : 0;
assign LED[1] = led_enable ? (cnt[26] ? ~pwm[4] : pwm[4]) : 0;
assign LED[2] = led_enable ? cnt[25] : 0;
assign LED[3] = led_enable ? ~cnt[25] : 0;
endmodule
我不想使用特定于供应商的DCM,因此使用66MHz时钟的简单位加法器可以解决这个问题。也许整个设计首先是错误的(例如,我可以使用两个时钟分频器并简单地翻转两个寄存器以实现(几乎)相同的事情),但我遇到了这种情况让我感到疑惑。 ..
从常规软件开发人员的角度来看,连续分配中的某些部分似乎是多余的。例如,可以使用额外的寄存器,因此看起来执行的工作量较少。例如:
module ledglow(input wire CLK,
input wire USER_RESET,
output wire LED[3:0]);
reg [26:0] cnt;
reg [4:0] pwm;
reg led_pair1;
reg led_pair2;
wire led_enable = ~USER_RESET;
always @(posedge CLK)
begin
if (led_enable)
begin
cnt <= cnt + 1;
pwm <= pwm[3:0] + (cnt[26] ? cnt[25:22] : ~cnt[25:22]);
end
else
begin
cnt <= 0;
pwm <= 0;
end
led_pair1 <= cnt[26] ? pwm[4] : ~pwm[4];
led_pair2 <= cnt[25];
end
assign LED[0] = led_enable ? led_pair1 : 0;
assign LED[1] = led_enable ? ~led_pair1 : 0;
assign LED[2] = led_enable ? led_pair2 : 0;
assign LED[3] = led_enable ? ~led_pair2: 0;
endmodule
我试图深入研究上述两种方法的合成器报告差异并查看HDL原理图,但对于像我这样缺乏经验的人来说这太复杂了。
毫无疑问,综合工具可以很好地优化组合逻辑,但假设右手边的表达式非常复杂,那么有没有办法说出这样的话?
if (some_reg_var) begin
assign net0 = 1;
assign net1 = 0;
end
else
begin
assign net0 = 0;
assign net1 = 1;
end
这样做甚至有意义吗?如果没有,在这种情况下引入寄存器以简化行为部分是否有意义?我相信至少有一些规则或大拇指。任何帮助表示赞赏。
答案 0 :(得分:2)
你的问题有点冗长,但我想我明白你的意思(如果我错了,请纠正我)。
你想知道是否有办法打破长期分配语句使用if / else逻辑,类似于一个始终阻止的reg?
通过这种方式,Verilog对我来说似乎总是有点滑稽,但仅仅因为你宣称'reg'数据类型并不意味着它被合成到寄存器。如果存在某种状态,它实际上只创建一个寄存器。话虽如此,以下两个陈述应该合成完全相同的事情:案例1:
wire a;
wire b;
assign a = b ? 0 : 1;
案例2:
reg a;
wire b;
always @(b)
if(b)
a <= 0;
else
a <= 1;
这两者都应该创建完全相同的逻辑(简单地说,一个带有=!b的逆变器)。即使在你声明了reg的第二种情况下,它实际上并不是一个寄存器实例,因为没有什么可记住的(所有输入都在灵敏度列表中)。
因此,您可以自由编写复杂的if / else逻辑来简化代码,这并不意味着您需要支付合成额外寄存器的代价。因此,随意编写它对您来说最舒适。 (如果确实使用了始终阻止,请确保为所有可能的情况分配,或者您将推断出您可能不想要的锁存器)。