I am trying to wrap my head around a mix of combinational and behavioral logic. I've got small FPGA with 4 LEDs and a 66 MHz clock input. The idea was to make two of them glowing (one rising, one falling) and another two blinking. So I came up with the following code:
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
I did not want to use a vendor specific DCM, and so simple bit adders with 66MHz clock works out the magic. Perhaps the whole design is wrong in a first place (for instance, I could have used two clock dividers and simply flip a bit of two registers to achieve (almost) the same thing), but I ran into this situation which made me wondering...
From a regular software developer's point of view, there are some parts in continuous assignments that seem redundant. For example, an extra register can be used and so it would seem that less work is performed. For instance:
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
I was trying to dig into synthesizer report differences for two approaches above and look at HDL schematics, but it way too complex for such an inexperienced guy like me.
No doubt synthesis tool optimizes the combinational logic very well, but assuming the the right hand side expressions are very complicated to be one-liners etc, is there a way to say something like this?
if (some_reg_var) begin
assign net0 = 1;
assign net1 = 0;
end
else
begin
assign net0 = 0;
assign net1 = 1;
end
Or does it even make sense to do so? If not, does it make sense to introduce registers in such cases to simplify the behavioral part? I am sure there are some rules or thumb at least. Any help is appreciated.