diff options
| author | Leonard Kugis <leonard@kug.is> | 2021-02-11 14:31:02 +0100 |
|---|---|---|
| committer | Leonard Kugis <leonard@kug.is> | 2021-02-11 14:31:02 +0100 |
| commit | 52f60a20c9d95ecf67b662589d4a4c1160ce0a2a (patch) | |
| tree | b0425a0acd757aa2a33c4db8ccaa897acea409b3 /hdl/clock_divider.v | |
| parent | 266f2ebc6322eeccf85fcc67eccc6d6200014dab (diff) | |
| download | turboswap-52f60a20c9d95ecf67b662589d4a4c1160ce0a2a.tar.gz | |
Reimplemented all HDL files
Diffstat (limited to 'hdl/clock_divider.v')
| -rw-r--r-- | hdl/clock_divider.v | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/hdl/clock_divider.v b/hdl/clock_divider.v new file mode 100644 index 0000000..adffe0e --- /dev/null +++ b/hdl/clock_divider.v @@ -0,0 +1,147 @@ +`timescale 1ns / 1ps + +module clock_divider ( + input wire clk_in, + input wire rst_n, + + output wire clk_12mhz, + output wire clk_50mhz, + output wire clk_sdio, + output wire clk_spi +); + + reg [1:0] div_counter_50mhz; + reg [7:0] div_counter_sdio; + reg [7:0] div_counter_spi; + + reg clk_50mhz_reg; + reg clk_sdio_reg; + reg clk_spi_reg; + + reg [7:0] sdio_div_ratio; + reg [7:0] spi_div_ratio; + + reg sdio_clk_en; + reg spi_clk_en; + + assign clk_12mhz = clk_in; + assign clk_50mhz = clk_50mhz_reg; + assign clk_sdio = sdio_clk_en ? clk_sdio_reg : 1'b0; + assign clk_spi = spi_clk_en ? clk_spi_reg : 1'b0; + + always @(posedge clk_in or negedge rst_n) begin + if (!rst_n) begin + div_counter_50mhz <= 2'b00; + clk_50mhz_reg <= 1'b0; + end else begin + div_counter_50mhz <= div_counter_50mhz + 1; + + case (div_counter_50mhz) + 2'b00: clk_50mhz_reg <= 1'b1; + 2'b01: clk_50mhz_reg <= 1'b1; + 2'b10: clk_50mhz_reg <= 1'b0; + 2'b11: clk_50mhz_reg <= 1'b0; + endcase + end + end + + always @(posedge clk_50mhz_reg or negedge rst_n) begin + if (!rst_n) begin + div_counter_sdio <= 8'd0; + clk_sdio_reg <= 1'b0; + sdio_div_ratio <= 8'd1; + end else if (sdio_clk_en) begin + if (div_counter_sdio >= sdio_div_ratio) begin + div_counter_sdio <= 8'd0; + clk_sdio_reg <= ~clk_sdio_reg; + end else begin + div_counter_sdio <= div_counter_sdio + 1; + end + end else begin + div_counter_sdio <= 8'd0; + clk_sdio_reg <= 1'b0; + end + end + + always @(posedge clk_50mhz_reg or negedge rst_n) begin + if (!rst_n) begin + div_counter_spi <= 8'd0; + clk_spi_reg <= 1'b0; + spi_div_ratio <= 8'd1; + end else if (spi_clk_en) begin + if (div_counter_spi >= spi_div_ratio) begin + div_counter_spi <= 8'd0; + clk_spi_reg <= ~clk_spi_reg; + end else begin + div_counter_spi <= div_counter_spi + 1; + end + end else begin + div_counter_spi <= 8'd0; + clk_spi_reg <= 1'b0; + end + end + + always @(posedge clk_50mhz_reg or negedge rst_n) begin + if (!rst_n) begin + sdio_clk_en <= 1'b0; + spi_clk_en <= 1'b0; + end else begin + sdio_clk_en <= 1'b1; + spi_clk_en <= 1'b1; + end + end + + task set_sdio_frequency; + input [7:0] divider; + begin + sdio_div_ratio <= divider; + end + endtask + + task set_spi_frequency; + input [7:0] divider; + begin + spi_div_ratio <= divider; + end + endtask + + task enable_sdio_clock; + input enable; + begin + sdio_clk_en <= enable; + end + endtask + + task enable_spi_clock; + input enable; + begin + spi_clk_en <= enable; + end + endtask + + function [7:0] calc_sdio_divider; + input [7:0] freq_mhz; + begin + if (freq_mhz == 0) + calc_sdio_divider = 8'd0; + else + calc_sdio_divider = 8'd25 / freq_mhz; + end + endfunction + + function [7:0] calc_spi_divider; + input [7:0] freq_mhz; + begin + if (freq_mhz == 0) + calc_spi_divider = 8'd0; + else + calc_spi_divider = 8'd25 / freq_mhz; + end + endfunction + + initial begin + sdio_div_ratio = calc_sdio_divider(8'd25); + spi_div_ratio = calc_spi_divider(8'd25); + end + +endmodule
\ No newline at end of file |
