/*
 * misc.v
 *
 * vim: ts=4 sw=4
 *
 * Misc peripheral functions
 *
 * Copyright (C) 2019-2020  Sylvain Munaut <tnt@246tNt.com>
 * SPDX-License-Identifier: CERN-OHL-S-2.0
 */

`default_nettype none

module misc (
	// PDM outputs
	output wire e1_vref_ct_pdm,
	output wire e1_vref_p_pdm,
	output wire e1_vref_n_pdm,

	output wire clk_tune_hi,
	output wire clk_tune_lo,

	// Button
	input  wire btn,

	// Ticks
	input  wire tick_e1_rx,
	input  wire tick_e1_tx,
	input  wire tick_usb_sof,

	// Reset request
	output wire        rst_req,

	// Wishbone
	input  wire [ 7:0] wb_addr,
	output reg  [31:0] wb_rdata,
	input  wire [31:0] wb_wdata,
	input  wire        wb_we,
	input  wire        wb_cyc,
	output reg         wb_ack,

	// Clock / Reset
	input  wire clk,
	input  wire rst
);

	// Signals
	// -------

	// Bus
	wire        bus_clr;
	reg         bus_we_boot;
	reg  [ 1:0] bus_we_pdm_clk;
	reg  [ 2:0] bus_we_pdm_e1;

	// Counters
	reg  [15:0] cnt_e1_rx;
	reg  [15:0] cap_e1_rx;
	reg  [15:0] cnt_e1_tx;
	reg  [15:0] cap_e1_tx;
	reg  [31:0] cnt_time;

	// PDM
	reg  [12:0] pdm_clk[0:1];
	reg  [ 8:0] pdm_e1[0:2];

	// Boot
	reg   [1:0] boot_sel;
	reg         boot_now;


	// Bus interface
	// -------------

	// Ack
	always @(posedge clk)
		wb_ack <= wb_cyc & ~wb_ack;

	assign bus_clr = ~wb_cyc | wb_ack;

	// Write enables
	always @(posedge clk)
		if (bus_clr | ~wb_we) begin
			bus_we_boot       <= 1'b0;
			bus_we_pdm_clk[0] <= 1'b0;
			bus_we_pdm_clk[1] <= 1'b0;
			bus_we_pdm_e1[0]  <= 1'b0;
			bus_we_pdm_e1[1]  <= 1'b0;
			bus_we_pdm_e1[2]  <= 1'b0;
		end else begin
			bus_we_boot       <= wb_addr == 4'h0;
			bus_we_pdm_clk[0] <= wb_addr == 4'h8;
			bus_we_pdm_clk[1] <= wb_addr == 4'h9;
			bus_we_pdm_e1[0]  <= wb_addr == 4'ha;
			bus_we_pdm_e1[1]  <= wb_addr == 4'hb;
			bus_we_pdm_e1[2]  <= wb_addr == 4'hc;
		end

	// Read mux
	always @(posedge clk)
		if (bus_clr)
			wb_rdata <= 32'h00000000;
		else
			case (wb_addr[3:0])
				4'h4:    wb_rdata <= { cap_e1_tx, cap_e1_rx };
				4'h7:    wb_rdata <= cnt_time;
				4'h8:    wb_rdata <= { pdm_clk[0][12], 19'h00000, pdm_clk[0][11:0] };
				4'h9:    wb_rdata <= { pdm_clk[1][12], 19'h00000, pdm_clk[1][11:0] };
				4'ha:    wb_rdata <= {  pdm_e1[0][8], 23'h000000,  pdm_e1[0][ 7:0] };
				4'hb:    wb_rdata <= {  pdm_e1[1][8], 23'h000000,  pdm_e1[1][ 7:0] };
				4'hc:    wb_rdata <= {  pdm_e1[2][8], 23'h000000,  pdm_e1[2][ 7:0] };
				default: wb_rdata <= 32'hxxxxxxxx;
			endcase


	// Counters
	// --------

	// E1 ticks
	always @(posedge clk or posedge rst)
		if (rst)
			cnt_e1_rx <= 16'h0000;
		else if (tick_e1_rx)
			cnt_e1_rx <= cnt_e1_rx + 1;

	always @(posedge clk or posedge rst)
		if (rst)
			cnt_e1_tx <= 16'h0000;
		else if (tick_e1_tx)
			cnt_e1_tx <= cnt_e1_tx + 1;

	always @(posedge clk)
		if (tick_usb_sof) begin
			cap_e1_rx <= cnt_e1_rx;
			cap_e1_tx <= cnt_e1_tx;
		end

	// Time counter
	always @(posedge clk)
		if (rst)
			cnt_time <= 32'h00000000;
		else
			cnt_time <= cnt_time + 1;


	// PDM outputs
	// -----------

	// Registers
	always @(posedge clk or posedge rst)
		if (rst) begin
			pdm_clk[0] <= 0; // 13'h1800;
			pdm_clk[1] <= 0; // 13'h1800;
			pdm_e1[0]  <= 0; // 9'h190;
			pdm_e1[1]  <= 0; // 9'h190;
			pdm_e1[2]  <= 0; // 9'h190;
		end else begin
			if (bus_we_pdm_clk[0])  pdm_clk[0] <= { wb_wdata[31], wb_wdata[11:0] };
			if (bus_we_pdm_clk[1])  pdm_clk[1] <= { wb_wdata[31], wb_wdata[11:0] };
			if (bus_we_pdm_e1[0])   pdm_e1[0]  <= { wb_wdata[31], wb_wdata[ 7:0] };
			if (bus_we_pdm_e1[1])   pdm_e1[1]  <= { wb_wdata[31], wb_wdata[ 7:0] };
			if (bus_we_pdm_e1[2])   pdm_e1[2]  <= { wb_wdata[31], wb_wdata[ 7:0] };
		end

	// PDM cores
	pdm #(
		.WIDTH(12),
		.PHY("ICE40"),
		.DITHER("YES")
	) pdm_clk_I[1:0] (
		.pdm    ({ clk_tune_hi,      clk_tune_lo      }),
		.cfg_val({ pdm_clk[1][11:0], pdm_clk[0][11:0] }),
		.cfg_oe ({ pdm_clk[1][12],   pdm_clk[0][12]   }),
		.clk    (clk),
		.rst    (rst)
	);

	pdm #(
		.WIDTH(8),
		.PHY("ICE40"),
		.DITHER("NO")
	) pdm_e1_I[2:0] (
		.pdm    ({ e1_vref_ct_pdm, e1_vref_p_pdm,  e1_vref_n_pdm  }),
		.cfg_val({ pdm_e1[2][7:0], pdm_e1[1][7:0], pdm_e1[0][7:0] }),
		.cfg_oe ({ pdm_e1[2][8],   pdm_e1[1][8],   pdm_e1[0][8]   }),
		.clk    (clk),
		.rst    (rst)
	);


	// DFU / Reboot
	// ------------

	always @(posedge clk or posedge rst)
		if (rst) begin
			boot_now <= 1'b0;
			boot_sel <= 2'b00;
		end else if (bus_we_boot) begin
			boot_now <= wb_wdata[2];
			boot_sel <= wb_wdata[1:0];
		end

	dfu_helper #(
		.TIMER_WIDTH(26),
		.BTN_MODE(3),
		.DFU_MODE(0)
	) dfu_I (
		.boot_sel(boot_sel),
		.boot_now(boot_now),
		.btn_pad (btn),
		.btn_val (),
		.rst_req (rst_req),
		.clk     (clk),
		.rst     (rst)
	);

endmodule // misc
