///////////////////////////////////////////////////////////////////////////////////////////////////
// File: binary_to_ascii_apb.v
//-------------------------------------------------------------------
//                                                                 
//  © 2022 Microchip Technology Inc. and its subsidiaries
//  All rights reserved.
//                                                                  
//  ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN 
//  ACCORDANCE WITH THE MICROCHIP LICENSE AGREEMENT AND MUST BE APPROVED 
//  IN ADVANCE IN WRITING.
//
//------------------------------------------------------------------
// Title       : binary_to_ascii_apb
// Created     : November-2018
// Description : The binary to ascii_apb module Convert 8-bit hex to 16-bit ascii value.
//    
// Revision    : 1.0 Initial Release
// Hierarchy   :
//                 -- binary_to_ascii_apb
//                   -- hex_to_ascii
//                     
//                
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////// 

`timescale 1ns / 100ps

module binary_to_ascii_apb( 
PCLK,
PENABLE,
PSEL,
PRESETN,
PWRITE,
PREADY,
PSLVERR,
PADDR,
PWDATA,
PRDATA
);

// APB interface signals
input  PCLK, PENABLE, PSEL, PRESETN, PWRITE;
input  [15:0] PADDR;
input  [31:0] PWDATA;
output reg [31:0] PRDATA;
output reg PREADY;
output PSLVERR;

//FSM state variable
parameter [1:0] idle = 2'b00, read_write = 2'b01, set_ready = 2'b10; 
reg  [1:0]   fsm; 

// registers to hold DSN, USERCODE, and DIGEST STATUS
reg [127:0] DSN_VALUE;
reg [7:0] DIGEST_RESP;
reg [31:0] USERCODE;

wire [15:0]  reg1_16;
wire [255:0] reg2_16;
wire [63:0]  reg3_16;

assign PSLVERR = 1'b0;

// Convert 8-bit hex to 16-bit ascii value

// DIGEST STATUS binary to ascii conversion
Binary2Ascii u1 (.ascii(reg1_16[15:0]), .binary(DIGEST_RESP));
// DSN binary to ascii conversion
Binary2Ascii u2 (.ascii(reg2_16[15:0]), .binary(DSN_VALUE[7:0]));
Binary2Ascii u3 (.ascii(reg2_16[31:16]), .binary(DSN_VALUE[15:8]));
Binary2Ascii u4 (.ascii(reg2_16[47:32]), .binary(DSN_VALUE[23:16]));
Binary2Ascii u5 (.ascii(reg2_16[63:48]), .binary(DSN_VALUE[31:24]));
Binary2Ascii u6 (.ascii(reg2_16[79:64]), .binary(DSN_VALUE[39:32]));
Binary2Ascii u7 (.ascii(reg2_16[95:80]), .binary(DSN_VALUE[47:40]));
Binary2Ascii u8 (.ascii(reg2_16[111:96]), .binary(DSN_VALUE[55:48]));
Binary2Ascii u9 (.ascii(reg2_16[127:112]), .binary(DSN_VALUE[63:56]));
Binary2Ascii u10 (.ascii(reg2_16[143:128]), .binary(DSN_VALUE[71:64]));
Binary2Ascii u11 (.ascii(reg2_16[159:144]), .binary(DSN_VALUE[79:72]));
Binary2Ascii u12 (.ascii(reg2_16[175:160]), .binary(DSN_VALUE[87:80]));
Binary2Ascii u13 (.ascii(reg2_16[191:176]), .binary(DSN_VALUE[95:88]));
Binary2Ascii u14 (.ascii(reg2_16[207:192]), .binary(DSN_VALUE[103:96]));
Binary2Ascii u15 (.ascii(reg2_16[223:208]), .binary(DSN_VALUE[111:104]));
Binary2Ascii u16 (.ascii(reg2_16[239:224]), .binary(DSN_VALUE[119:112]));
Binary2Ascii u17 (.ascii(reg2_16[255:240]), .binary(DSN_VALUE[127:120]));
// USERCODE binary to ascii conversion
Binary2Ascii u18 (.ascii(reg3_16[15:0]), .binary(USERCODE[7:0]));
Binary2Ascii u19 (.ascii(reg3_16[31:16]), .binary(USERCODE[15:8]));
Binary2Ascii u20 (.ascii(reg3_16[47:32]), .binary(USERCODE[23:16]));
Binary2Ascii u21 (.ascii(reg3_16[63:48]), .binary(USERCODE[31:24]));

always@(posedge PCLK)
if(~PRESETN)
    begin
     fsm <= idle;
     DSN_VALUE <= 128'b0;
     DIGEST_RESP <= 8'b0;
     USERCODE <= 32'b0;
     PREADY <= 1'b1;
	 PRDATA <= 32'b0;	
    end
else
    begin
     case (fsm)
      idle: begin
              if(~PSEL)
                begin
                 fsm <= idle;
                end
              else
                begin 
                 fsm <= read_write;
                 PREADY <= 1'b0;
                end
             end
      read_write: begin
              fsm <= set_ready;
              PREADY <= 1'b0;
              if((PENABLE) && (PWRITE))  //APB Write
                begin 
                 case (PADDR[15:0])
                   16'h1000: begin   
                              DSN_VALUE [31:0] <= PWDATA;
                             end
                   16'h1004: begin
                              DSN_VALUE [63:32] <= PWDATA;
                             end
                   16'h1008: begin
                              DSN_VALUE [95:64] <= PWDATA;
                             end
                   16'h100C: begin
                              DSN_VALUE [127:96] <= PWDATA;
                             end
                   16'h1010: begin
                              DIGEST_RESP [7:0] <= PWDATA[7:0];
                             end
                   16'h1014: begin
                              USERCODE [31:0] <= PWDATA;
                             end     
                    default: begin
                              DSN_VALUE [31:0] <= PWDATA;
                             end
                 endcase
                end
              else if ((PENABLE) && (!PWRITE)) //APB Read
                begin
                 case (PADDR[15:0])
                   16'h2000: begin
                              PRDATA[15:0] <= reg2_16[15:0];
                             end
                   16'h2002: begin
                              PRDATA[15:0] <= reg2_16[31:16];
                             end
                   16'h2004: begin
                              PRDATA[15:0] <= reg2_16[47:32];
                             end
                   16'h2006: begin
                              PRDATA[15:0] <= reg2_16[63:48];
                             end
                   16'h2008: begin
                              PRDATA[15:0] <= reg2_16[79:64];
                             end
                   16'h200A: begin
                              PRDATA[15:0] <= reg2_16[95:80];
                             end
                   16'h200C: begin
                              PRDATA[15:0] <= reg2_16[111:96];
                             end
                   16'h200E: begin
                              PRDATA[15:0] <= reg2_16[127:112];
                             end
                   16'h2010: begin
                              PRDATA[15:0] <= reg2_16[143:128];
                             end
                   16'h2012: begin
                              PRDATA[15:0] <= reg2_16[159:144];
                             end
                   16'h2014: begin
                              PRDATA[15:0] <= reg2_16[175:160];
                             end
                   16'h2016: begin
                              PRDATA[15:0] <= reg2_16[191:176];
                             end
                   16'h2018: begin
                              PRDATA[15:0] <= reg2_16[207:192];
                             end
                   16'h201A: begin
                              PRDATA[15:0] <= reg2_16[223:208];
                             end
                   16'h201C: begin
                              PRDATA[15:0] <= reg2_16[239:224];
                             end
                   16'h201E: begin
                              PRDATA[15:0] <= reg2_16[255:240];
                             end
                   16'h2020: begin
                              PRDATA[15:0] <= reg1_16[15:0];
                             end
                   16'h2022: begin
                              PRDATA[15:0] <= reg3_16[15:0];
                             end
                   16'h2024: begin
                              PRDATA[15:0] <= reg3_16[31:16];
                             end
                   16'h2026: begin
                              PRDATA[15:0] <= reg3_16[47:32];
                             end
                   16'h2028: begin
                              PRDATA[15:0] <= reg3_16[63:48];
                             end
                   default:  begin
                              PRDATA <= 32'h00000000;
                             end
                 endcase
                end
             end
      set_ready: begin
              fsm <= idle;
              PREADY <= 1'b1;
             end
      default: begin
                fsm <= idle;
               end
     endcase
    end
endmodule

