`timescale 1ns / 1ps module generator #( parameter DATA_WIDTH = 14, parameter ZERO_LEVEL = 8192 // 8192 or 0 ) ( input clk_dac, input rst, input start, input [31:0] pulse_width, input [31:0] pulse_period, input [DATA_WIDTH-1:0] pulse_height, input [15:0] pulse_num, input request, output logic [DATA_WIDTH-1:0] dac_out, output logic done ); logic [DATA_WIDTH-1:0] pulse_height_reg; logic [31:0] pulse_width_reg, pulse_period_reg; logic [15:0] pulse_num_reg; logic [15:0] cnt_pulse_num; logic [31:0] cnt_pulse_period; logic enable, synced; always @(posedge clk_dac) begin if (rst) begin pulse_height_reg <= ZERO_LEVEL; pulse_width_reg <= 0; pulse_period_reg <= 0; pulse_num_reg <= 0; cnt_pulse_num <= 0; cnt_pulse_period <= 0; dac_out <= ZERO_LEVEL; done <= 0; enable <= 0; synced <= 0; end else begin // wait start for updating registers if (start & !enable) begin enable <= 1; pulse_width_reg <= pulse_width; pulse_period_reg <= pulse_period; pulse_num_reg <= pulse_num; pulse_height_reg <= pulse_height; end // main work cycle if (enable) begin if (cnt_pulse_num != pulse_num_reg) begin // wait for synchronization with sampler if (!synced) begin if (request & done) begin synced <= 1; done <= 0; end else done <= 1; end else begin if (cnt_pulse_period != pulse_period_reg) begin if (cnt_pulse_period < pulse_width_reg) dac_out <= pulse_height_reg; else dac_out <= ZERO_LEVEL; cnt_pulse_period++; end else begin cnt_pulse_num++; cnt_pulse_period <= 0; synced <= 0; dac_out <= ZERO_LEVEL; end end end else begin cnt_pulse_num <= 0; enable <= 0; end end end end endmodule