我试图将我的头脑围绕在组合逻辑和行为逻辑的混合中。我有带有 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
或者这样做是否有意义?如果不是,在这种情况下引入寄存器以简化行为部分是否有意义?我相信至少有一些规则或经验。任何帮助表示赞赏。