`timescale 1ns / 1ps module Power2ClkDivider ( clk_i, rst_i, valid_i, signal_o, rising_edge_o, falling_edge_o ); //================================================================================ // // PARAMETER/LOCALPARAM // //================================================================================ parameter DIVISOR_POWER = 2; //================================================================================ // // PORTS // //================================================================================ input clk_i; input rst_i; input valid_i; output reg signal_o; output reg rising_edge_o; output reg falling_edge_o; //================================================================================ // // REG/WIRE // //================================================================================ wire clk_div_flag; //================================================================================ // // CODING // //================================================================================ //initial begin // if (DIVISOR_POWER < 1) begin // $error("parameter DIVISOR_POWER of module power2_clk_divider must be greater then 0"); // $stop; // end //end generate if (DIVISOR_POWER < 2) begin assign clk_div_flag = 1'b1; end else begin reg [DIVISOR_POWER-2:0] clk_div_cnt; always @(posedge clk_i or posedge rst_i) begin if (rst_i) begin clk_div_cnt <= {DIVISOR_POWER{1'b1}}; end else if (valid_i) begin clk_div_cnt <= clk_div_cnt + 1; end else begin clk_div_cnt <= {DIVISOR_POWER{1'b1}}; end end assign clk_div_flag = &clk_div_cnt; end endgenerate always @(posedge clk_i or posedge rst_i) begin if (rst_i) begin signal_o <= 1'b0; rising_edge_o <= 1'b0; falling_edge_o <= 1'b0; end else if (valid_i) begin if (clk_div_flag) begin signal_o <= ~signal_o; end rising_edge_o <= ~signal_o & clk_div_flag; falling_edge_o <= signal_o & clk_div_flag; end else begin signal_o <= 1'b0; rising_edge_o <= 1'b0; falling_edge_o <= 1'b0; end end endmodule