`timescale 1 ns / 1 ps module trans_timer# ( parameter CLK_PERIOD = 20 , parameter START_DELAY_NS = 100000, parameter SPI_TRANS_PERIOD = 1500 ) ( input clk , input rst_n , input [32-1:0] update_period , input enable , output trans_round , output trans_pulse ); //***************************************************************************** // localparam definition //***************************************************************************** localparam T_START_DLY = START_DELAY_NS/CLK_PERIOD-1 ; localparam T_TRANS = SPI_TRANS_PERIOD/CLK_PERIOD ; //***************************************************************************** // Internal register and wire declarations //***************************************************************************** reg [32-1:0] start_clocks_cnt ; reg [32-1:0] stop_clocks_cnt ; reg start ; reg [32-1:0] update_clocks_cnt ; reg update_r ; reg [ 8-1:0] clk_cnt ; reg trans_r ; //***************************************************************************** always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) start_clocks_cnt <= 0; else if ( enable && start_clocks_cnt != T_START_DLY ) start_clocks_cnt <= start_clocks_cnt + 1'b1; else if ( ~enable ) start_clocks_cnt <= 0; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) stop_clocks_cnt <= 0; else if ( enable ) stop_clocks_cnt <= 0; else stop_clocks_cnt <= stop_clocks_cnt + 1'b1; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) start <= 1'b0; else if ( start_clocks_cnt == T_START_DLY ) start <= 1'b1; else if ( stop_clocks_cnt == update_period ) start <= 1'b0; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) update_clocks_cnt <= 0; else if ( ~start ) update_clocks_cnt <= 0; else if ( update_clocks_cnt == update_period - 1 ) update_clocks_cnt <= 0; else update_clocks_cnt <= update_clocks_cnt + 1'b1; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) update_r <= 0; else if ( start && update_clocks_cnt == 0 ) update_r <= 1; else update_r <= 0; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) clk_cnt <= 0; else if ( ~start ) clk_cnt <= 0; else if ( update_clocks_cnt == update_period - 1 ) clk_cnt <= 0; else if ( clk_cnt == T_TRANS-1 ) clk_cnt <= 0; else clk_cnt <= clk_cnt + 1'b1; end always @ ( posedge clk or negedge rst_n ) begin if( !rst_n ) trans_r <= 0; else if ( clk_cnt == T_TRANS-1 ) trans_r <= 1; else trans_r <= 0; end //***************************************************************************** // Wire assignment //***************************************************************************** assign trans_round = update_r; assign trans_pulse = trans_r; endmodule