// SPDX-FileCopyrightText: Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`default_nettype none
/*
 *  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.
 *
 */

module simpleuart_wb # (
    parameter BASE_ADR = 32'h 2000_0000,
    parameter CLK_DIV = 8'h00,
    parameter DATA = 8'h04,
    parameter CONFIG = 8'h08
) (
    input wb_clk_i,
    input wb_rst_i,

    input [31:0] wb_adr_i,      // (verify): input address was originaly 22 bits , why ? (max number of words ?)
    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

);
    wire [31:0] simpleuart_reg_div_do;
    wire [31:0] simpleuart_reg_dat_do;
    wire [31:0] simpleuart_reg_cfg_do;
    wire reg_dat_wait;

    wire resetn = ~wb_rst_i;
    wire valid = wb_stb_i && wb_cyc_i; 
    wire simpleuart_reg_div_sel = valid && (wb_adr_i == (BASE_ADR | CLK_DIV));
    wire simpleuart_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
    wire simpleuart_reg_cfg_sel = valid && (wb_adr_i == (BASE_ADR | CONFIG));

    wire [3:0] reg_div_we = simpleuart_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000; 
    wire reg_dat_we = simpleuart_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0;      // simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0
    wire reg_cfg_we = simpleuart_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 = simpleuart_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable

    assign wb_dat_o = simpleuart_reg_div_sel ? simpleuart_reg_div_do:
		      simpleuart_reg_cfg_sel ? simpleuart_reg_cfg_do:
					       simpleuart_reg_dat_do;
    assign wb_ack_o = (simpleuart_reg_div_sel || simpleuart_reg_dat_sel
			|| simpleuart_reg_cfg_sel) && (!reg_dat_wait);
    
    simpleuart simpleuart (
        .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  (simpleuart_reg_div_do),

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

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

endmodule

module simpleuart (
    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;

    wire reg_ena_do;

    assign reg_div_do = cfg_divider;
    assign reg_ena_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];
        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
