`default_nettype none
/*
 *  SPDX-FileCopyrightText: 2015 Clifford Wolf
 *  PicoSoC - A simple example SoC using PicoRV32
 *
 *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  SPDX-License-Identifier: ISC
 */

module simpleuartA_wb(
    `ifdef USE_POWER_PINS
    input  wire        vccd1      , // User area 1 1.8V supply
    input  wire        vssd1      , // User area 1 digital ground
    `endif
    input wb_clk_i,
    input wb_rst_i,

    input [1:0] wb_adr_i,
    input [31:0] wb_dat_i,
    input [3:0]  wb_sel_i,
    input wb_we_i,
    input wb_cyc_i,
    input wb_stb_i,

    output wb_ack_o,
    output [31:0] wb_dat_o,

    output uart_enabled,
    output ser_tx,
    input  ser_rx

);

    localparam CLK_DIV = 0;
    localparam DATA = 1;
    localparam CONFIG = 2;
    wire [31:0] simpleuartA_reg_div_do;
    wire [31:0] simpleuartA_reg_dat_do;
    wire [31:0] simpleuartA_reg_cfg_do;
    wire reg_dat_wait;

    wire resetn = ~wb_rst_i;
    wire valid = wb_stb_i && wb_cyc_i; 
    wire simpleuartA_reg_div_sel = valid && (wb_adr_i == CLK_DIV);
    wire simpleuartA_reg_dat_sel = valid && (wb_adr_i == DATA);
    wire simpleuartA_reg_cfg_sel = valid && (wb_adr_i == CONFIG);

    wire [3:0] reg_div_we = simpleuartA_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000; 
    wire reg_dat_we = simpleuartA_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0;      // simpleuartA_reg_dat_sel ? mem_wstrb[0] : 1'b 0
    wire reg_cfg_we = simpleuartA_reg_cfg_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0; 

    wire [31:0] mem_wdata = wb_dat_i;
    //wire reg_dat_re = simpleuartA_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable //original
    wire reg_dat_re = simpleuartA_reg_dat_sel && ~wb_we_i; // read_enable //original

    assign wb_dat_o = simpleuartA_reg_div_sel ? simpleuartA_reg_div_do:
		      simpleuartA_reg_cfg_sel ? simpleuartA_reg_cfg_do:
					       simpleuartA_reg_dat_do;
    assign wb_ack_o = (simpleuartA_reg_div_sel || simpleuartA_reg_dat_sel
			|| simpleuartA_reg_cfg_sel) && (!reg_dat_wait);
    
    simpleuartA simpleuartA (
        .clk    (wb_clk_i),
        .resetn (resetn),

        .ser_tx      (ser_tx),
        .ser_rx      (ser_rx),
        .enabled     (uart_enabled),

        .reg_div_we  (reg_div_we), 
        .reg_div_di  (mem_wdata),
        .reg_div_do  (simpleuartA_reg_div_do),

        .reg_cfg_we  (reg_cfg_we), 
        .reg_cfg_di  (mem_wdata),
        .reg_cfg_do  (simpleuartA_reg_cfg_do),

        .reg_dat_we  (reg_dat_we),
        .reg_dat_re  (reg_dat_re),
        .reg_dat_di  (mem_wdata),
        .reg_dat_do  (simpleuartA_reg_dat_do),
        .reg_dat_wait(reg_dat_wait)
    );

endmodule

module simpleuartA (
    input clk,
    input resetn,

    output enabled,
    output ser_tx,
    input  ser_rx,

    input   [3:0] reg_div_we,         
    input  [31:0] reg_div_di,         
    output [31:0] reg_div_do,         

    input   	  reg_cfg_we,         
    input  [31:0] reg_cfg_di,         
    output [31:0] reg_cfg_do,         

    input         reg_dat_we,         
    input         reg_dat_re,         
    input  [31:0] reg_dat_di,
    output [31:0] reg_dat_do,
    output        reg_dat_wait
);
    reg [31:0] cfg_divider;
    reg        enabled;

    reg [3:0] recv_state;
    reg [31:0] recv_divcnt;
    reg [7:0] recv_pattern;
    reg [7:0] recv_buf_data;
    reg recv_buf_valid;

    reg [9:0] send_pattern;
    reg [3:0] send_bitcnt;
    reg [31:0] send_divcnt;
    reg send_dummy;

    assign reg_div_do = cfg_divider;
    assign reg_cfg_do = {31'd0, enabled};

    assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
    assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;

    always @(posedge clk) begin
        if (!resetn) begin
            cfg_divider <= 1;
	    enabled <= 1'b0;
        end else begin
            if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
            if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
            if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
            if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
            //if (reg_cfg_we) enabled <= reg_div_di[0]; // original one
            if (reg_cfg_we) enabled <= reg_cfg_di[0];
        end
    end

    always @(posedge clk) begin
        if (!resetn) begin
            recv_state <= 0;
            recv_divcnt <= 0;
            recv_pattern <= 0;
            recv_buf_data <= 0;
            recv_buf_valid <= 0;
        end else begin
            recv_divcnt <= recv_divcnt + 1;
            if (reg_dat_re)
                recv_buf_valid <= 0;
            case (recv_state)
                0: begin
                    if (!ser_rx && enabled)
                        recv_state <= 1;
                    recv_divcnt <= 0;
                end
                1: begin
                    if (2*recv_divcnt > cfg_divider) begin
                        recv_state <= 2;
                        recv_divcnt <= 0;
                    end
                end
                10: begin
                    if (recv_divcnt > cfg_divider) begin
                        recv_buf_data <= recv_pattern;
                        recv_buf_valid <= 1;
                        recv_state <= 0;
                    end
                end
                default: begin
                    if (recv_divcnt > cfg_divider) begin
                        recv_pattern <= {ser_rx, recv_pattern[7:1]};
                        recv_state <= recv_state + 1;
                        recv_divcnt <= 0;
                    end
                end
            endcase
        end
    end

    assign ser_tx = send_pattern[0];

    always @(posedge clk) begin
        if (reg_div_we && enabled)
            send_dummy <= 1;
        send_divcnt <= send_divcnt + 1;
        if (!resetn) begin
            send_pattern <= ~0;
            send_bitcnt <= 0;
            send_divcnt <= 0;
            send_dummy <= 1;
        end else begin
            if (send_dummy && !send_bitcnt) begin
                send_pattern <= ~0;
                send_bitcnt <= 15;
                send_divcnt <= 0;
                send_dummy <= 0;
            end else
            if (reg_dat_we && !send_bitcnt) begin
                send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
                send_bitcnt <= 10;
                send_divcnt <= 0;
            end else
            if (send_divcnt > cfg_divider && send_bitcnt) begin
                send_pattern <= {1'b1, send_pattern[9:1]};
                send_bitcnt <= send_bitcnt - 1;
                send_divcnt <= 0;
            end
        end
    end
endmodule
`default_nettype wire