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
|