105 lines
3.3 KiB
Verilog
105 lines
3.3 KiB
Verilog
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
|