summaryrefslogtreecommitdiffhomepage
path: root/source/bin_to_ascii.v
blob: 12464dca178489a5ed6aba9bdf539689911d0fcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 *       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