/* * bin_to_asc.v * * Copyright (C) 2018, 2019 Mind Chasers Inc. * * 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. * * function: Convert binary to ASCII ( 16-bit or 8-bit ) * */ `timescale 1ns /10ps module bin_to_ascii( input rstn, input clk, input width, // 0 for 8-bit, 1 for 16-bit // mdio interface input we_i, // latch the data and start input [15:0] d_in, // binary in // mdio controller interface output reg run, // block has the output bus output reg done, // block is done it's processing, use as an internal reset input busy, // instruct the block to hold off on writing // write to output port output we_o, // asserts we for each ascii word to write out output reg [6:0] d_out // ascii out ); // ascii codes we use localparam ASCII_ = 7'h5f, ASCIIq = 7'h3f, LF = 7'h0a, CR = 7'h0d; reg [2:0] cnt; // count the nibbles, last two are for CR and LF reg [3:0] d_bin_in_4; reg [15:0] d; // internally latched data /* start running on we */ always @(posedge clk or negedge rstn) begin if ( !rstn | done ) run <= 1'b0; else if ( we_i ) run <= 1'b1; end /* register the incoming data */ always @(posedge clk, negedge rstn) begin if ( !rstn ) d <= 16'h0; else if ( we_i ) d <= d_in; end /* increment the counter when running, start at 0 or 2 depending on width */ always @(posedge clk or negedge rstn) begin if ( !rstn | done ) cnt <= 3'd0; else if ( we_i & ~width ) cnt <= 3'd2; else if ( run ) cnt <= cnt + 1; end always @(posedge clk or negedge rstn) begin if ( !rstn ) done <= 1'b0; else if ( cnt == 3'd5 ) done <= 1'b1; else done <= 1'b0; end assign we_o = run && ~done; /* d_bin_in_4 mux */ always@(*) begin case ( cnt ) 3'b000: d_bin_in_4 = d[15:12]; 3'b001: d_bin_in_4 = d[11:8]; 3'b010: d_bin_in_4 = d[7:4]; 3'b011: d_bin_in_4 = d[3:0]; default: d_bin_in_4 = d[3:0]; endcase end /* perform the conversion */ always @(*) begin d_out = { 3'b011, d_bin_in_4 }; if ( cnt < 3'd4 && d_bin_in_4 >= 4'd10 ) case( d_bin_in_4 ) 4'ha : d_out = 7'h61; 4'hb : d_out = 7'h62; 4'hc : d_out = 7'h63; 4'hd : d_out = 7'h64; 4'he : d_out = 7'h65; 4'hf : d_out = 7'h66; default : d_out = 7'h3f; // question mark endcase else if ( cnt == 3'd4 ) d_out = CR; else if ( cnt == 3'd5 ) d_out = LF; end endmodule