lin-win-share/DA4008_V1.3/rtl/comm/pulse_generator.sv

54 lines
1.6 KiB
Systemverilog

module pulse_generator #(
parameter DATA_WIDTH = 16
)(
input logic clk,
input logic rst_n,
input logic pulse_en,
input logic [DATA_WIDTH-1:0] delay,
input logic [DATA_WIDTH-1:0] width,
input logic inv_en,
output logic pulse
);
logic [DATA_WIDTH-1:0] counter; // 用于延迟和宽度计数
logic pulse_delay_done;
logic pulse_width_done;
assign pulse_delay_done = (counter == delay);
assign pulse_width_done = (counter == width);
localparam SM_IDLE = 0;
localparam SM_WAIT = 1;
localparam SM_WORK = 2;
logic [1:0] current_state;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
current_state <= SM_IDLE;
end else begin
case(current_state)
SM_IDLE: current_state <= pulse_en ? SM_WAIT : SM_IDLE;
SM_WAIT: current_state <= pulse_delay_done ? SM_WORK : SM_WAIT;
SM_WORK: current_state <= pulse_width_done ? SM_IDLE : SM_WORK;
endcase
end
end
always @(posedge clk) begin
case(current_state)
SM_IDLE: counter <= 1;
SM_WAIT: counter <= pulse_delay_done ? 1 : (counter + 1);
SM_WORK: counter <= pulse_width_done ? 1 : (counter + 1);
endcase
end
always @(posedge clk) begin
case(current_state)
SM_IDLE: pulse <= inv_en;
SM_WAIT: pulse <= pulse_delay_done ? ~inv_en : inv_en;
SM_WORK: pulse <= pulse_width_done ? inv_en : ~inv_en;
endcase
end
endmodule