module ramp_gen ( // system ports input clk, input rst_n, input [1:0] dac_mode_sel, input cen, input [7:0] step, // 8-bit step value input fixed, input [7:0] fixed_value, // 8-bit fixed value input [31:0] ifs, output [7:0] ramp [63:0], // 64 channels of 8-bit output output ramp_vld ); ////////////////////////////////////////////////////////////// // Counter to generate ramp_add_en enable signal ////////////////////////////////////////////////////////////// reg [31:0] cnt_c; wire add_cnt = cen & ~fixed; wire end_cnt = add_cnt && (cnt_c == ifs - 1); wire [31:0] cnt_n = end_cnt ? 32'h0 : add_cnt ? cnt_c + 1'b1 : cnt_c; always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt_c <= 32'h0; else cnt_c <= cnt_n; end reg ramp_add_en; always @(posedge clk or negedge rst_n) begin if (!rst_n) ramp_add_en <= 1'b0; else ramp_add_en <= end_cnt | ((ifs == 32'b0) & cen) | fixed; end ////////////////////////////////////////////////////////////// // Pre-calculated step multiples (for special mode) ////////////////////////////////////////////////////////////// wire [7:0] step2_w = step << 1; wire [7:0] step4_w = step << 2; wire [7:0] step8_w = step << 3; wire [7:0] step16_w = step << 4; wire [7:0] step32_w = step << 5; wire [7:0] step64_w = step << 6; ////////////////////////////////////////////////////////////// // Generate 64 independent always blocks using generate ////////////////////////////////////////////////////////////// genvar i; generate for (i = 0; i < 64; i = i + 1) begin : ramp_chan reg [7:0] ramp_r; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin ramp_r <= 8'b0; end else if (fixed) begin ramp_r <= fixed_value; end else if (ifs == 32'b0) begin // Special mode: ifs == 0 if (cen & ~ramp_add_en) begin // Initial phase loading: channel i gets (i+1)*step ramp_r <= (i + 1) * step; end else if (ramp_add_en) begin // Add large step each cycle (select 64¡Ástep or 32¡Ástep according to dac_mode_sel[1]) ramp_r <= ramp_r + (dac_mode_sel[1] ? step64_w : step32_w); end else begin // Hold current value ramp_r <= ramp_r; end end else begin // Normal mode: add step every ifs cycles if (ramp_add_en) begin ramp_r <= ramp_r + step; end else begin ramp_r <= ramp_r; end end end // Connect internal register to output port assign ramp[i] = ramp_r; end endgenerate ////////////////////////////////////////////////////////////// // Output valid signal ////////////////////////////////////////////////////////////// reg en_dly; always @(posedge clk or negedge rst_n) begin if (!rst_n) en_dly <= 1'b0; else en_dly <= cen | fixed; end assign ramp_vld = en_dly; endmodule