This is my first post and my first attempt at using a PLD.
I have written some code to make a breathing LED with 7 set points. The code produces a pwm output according to the first set point. It then slowly increases/decreases the pwm towards the next set point (7 in total).
The code works but I think it can be done better as I need to put 16 instantiations of this into a Lattice 4256 CPLD (not possible with my code). I am keen to learn how a professional Verilog programmer would tackle this. Many thanks in advance for your support. PWM Generation
module LED_breath (led, tmr_clk);
output reg led;
input tmr_clk;
reg [7:0] cnt;
reg [6:0] pwm_cnt;
reg [6:0] pwm_val;
reg [2:0] pat_cnt;
reg [9:0] delay_cnt;
reg [6:0] cur_pat;
reg [6:0] nxt_pat;
parameter pattern = {7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00};
always @(posedge tmr_clk)
begin
pwm_cnt = cnt[7] ? ~cnt[6:0] : cnt[6:0]; //Generate triangle wave
if(pwm_cnt > pwm_val) //Generate pwm
led <= 1'b0;
if(pwm_cnt < pwm_val)
led <= 1'b1;
cnt = cnt + 1;
end
always @(posedge tmr_clk) //breathing pattern
begin
if(!delay_cnt) //Add delay
begin
cur_pat <= ((pattern >> (7*pat_cnt)) & 7'b1111111); //Find correct pattern No. from parameter list
if((pat_cnt+1) == 8) //Check for last pattern - overflow, set to 0
nxt_pat <= (pattern & 7'b1111111);
else
nxt_pat <= ((pattern >> (7*(pat_cnt+1))) & 7'b1111111);
if(pwm_val == nxt_pat) //If pwm is at max or min increment count to get next pattern
pat_cnt <= pat_cnt + 1;
if(cur_pat <= nxt_pat) //Current pattern < next pattern, count up
pwm_val <= pwm_val + 1;
if(cur_pat >= nxt_pat) //Current pattern < next pattern, count down
pwm_val <= pwm_val - 1;
end
delay_cnt <= delay_cnt + 1;
end
endmodule
module top (led_0, led_1, led_2, led_3);
output led_0;
output led_1;
output led_2;
output led_3;
defparam I1.TIMER_DIV = "128";
OSCTIMER I1 (.DYNOSCDIS(1'b0), .TIMERRES(1'b0), .OSCOUT(osc_clk), .TIMEROUT(tmr_clk));
LED_breath #(.pattern({7'h20, 7'h70, 7'h50, 7'h70, 7'h40, 7'h10, 7'h60, 7'h10})) led_A(
.led (led_0),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h70, 7'h10, 7'h30, 7'h20, 7'h60, 7'h40, 7'h70, 7'h10})) led_B(
.led (led_1),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h10, 7'h30, 7'h10, 7'h18, 7'h40, 7'h50, 7'h30, 7'h60})) led_C(
.led (led_2),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h50, 7'h70, 7'h40, 7'h50, 7'h40, 7'h70, 7'h60, 7'h70})) led_D(
.led (led_3),
.tmr_clk (tmr_clk)
);
endmodule