aboutsummaryrefslogtreecommitdiffstats
path: root/hdl/clock_divider.v
diff options
context:
space:
mode:
authorLeonard Kugis <leonard@kug.is>2021-02-11 14:31:02 +0100
committerLeonard Kugis <leonard@kug.is>2021-02-11 14:31:02 +0100
commit52f60a20c9d95ecf67b662589d4a4c1160ce0a2a (patch)
treeb0425a0acd757aa2a33c4db8ccaa897acea409b3 /hdl/clock_divider.v
parent266f2ebc6322eeccf85fcc67eccc6d6200014dab (diff)
downloadturboswap-52f60a20c9d95ecf67b662589d4a4c1160ce0a2a.tar.gz
Reimplemented all HDL files
Diffstat (limited to 'hdl/clock_divider.v')
-rw-r--r--hdl/clock_divider.v147
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