https://blackmesalabs.wordpress.com/2016/10/24/sump2-96-msps-logic-analyzer-for-22/
[BML_sump2] / sump2 / source / mesa_byte2ascii.v
1 /* ****************************************************************************\r
2 -- Source file: mesa_byte2ascii.v                \r
3 -- Date:        October 4, 2015\r
4 -- Author:      khubbard\r
5 -- Description: Convert a binary byte to two ASCII nibs for UART transmission.\r
6 --              Must handshake with both byte sender and UART for busy status.\r
7 --              Also tracks a tx_done signal that queues up a "\n" to be sent.\r
8 -- Language:    Verilog-2001\r
9 -- Simulation:  Mentor-Modelsim \r
10 -- Synthesis:   Lattice     \r
11 -- License:     This project is licensed with the CERN Open Hardware Licence\r
12 --              v1.2.  You may redistribute and modify this project under the\r
13 --              terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl).\r
14 --              This project is distributed WITHOUT ANY EXPRESS OR IMPLIED\r
15 --              WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY\r
16 --              AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL\r
17 --              v.1.2 for applicable Conditions.\r
18 --\r
19 -- Revision History:\r
20 -- Ver#  When      Who      What\r
21 -- ----  --------  -------- ---------------------------------------------------\r
22 -- 0.1   10.04.15  khubbard Creation\r
23 -- ***************************************************************************/\r
24 `default_nettype none // Strictly enforce all nets to be declared\r
25 \r
26 module mesa_byte2ascii\r
27 (\r
28   input  wire         clk,\r
29   input  wire         reset,\r
30   input  wire [7:0]   tx_byte_d,\r
31   input  wire         tx_byte_en,\r
32   output wire         tx_byte_busy,\r
33   input  wire         tx_byte_done,\r
34   output reg  [7:0]   tx_char_d,\r
35   output wire         tx_char_en,\r
36   input  wire         tx_char_busy,\r
37   input  wire         tx_char_idle\r
38 );// module mesa_byte2ascii\r
39 \r
40   reg           tx_done_jk;\r
41   reg           tx_done_char;\r
42   reg           tx_en;\r
43   reg           tx_en_p1;\r
44   reg           tx_busy_jk;\r
45   reg  [1:0]    tx_fsm;\r
46   reg  [7:0]    tx_byte_sr;\r
47   wire          tx_uart_busy;\r
48   reg           tx_uart_busy_p1;\r
49   reg  [7:0]    tx_uart_busy_sr;\r
50   wire [3:0]    tx_nib_bin;\r
51 \r
52   `define ascii_lf       8'H0a\r
53  \r
54   assign tx_uart_busy = tx_char_busy;\r
55   assign tx_char_en   = tx_en;\r
56   assign tx_byte_busy = tx_busy_jk | tx_byte_en;\r
57 \r
58 //-----------------------------------------------------------------------------\r
59 // When a binary byte is sent to transmit, immediately assert tx_busy\r
60 // then convert 1of2 nibbles to ASCII and send out until byte is done.\r
61 // If tx_done asserts, wait for tx_busy to drop and then send a "\n".\r
62 // 0x30 = "0"\r
63 // 0x39 = "9"\r
64 // 0x41 = "A"\r
65 // 0x46 = "F"\r
66 // 0x61 = "a"\r
67 // 0x66 = "f"\r
68 //-----------------------------------------------------------------------------\r
69 always @ ( posedge clk ) begin : proc_tx  \r
70   tx_done_char    <= 0;\r
71   tx_en           <= 0;\r
72   tx_en_p1        <= tx_en;\r
73   tx_uart_busy_p1 <= tx_uart_busy;\r
74   tx_uart_busy_sr <= { tx_uart_busy_sr[6:0], tx_uart_busy };\r
75 \r
76   // Remember that the transmission was complete to queue up a "\n"\r
77   if ( tx_byte_done == 1 ) begin\r
78     tx_done_jk <= 1;\r
79   end\r
80 \r
81   // Deassert tx_busy_jk on falling edge of UART busy when no more nibbles\r
82 //if ( tx_fsm == 2'b00 && tx_uart_busy_p1 == 1 && tx_uart_busy == 0 ) begin\r
83   if ( tx_fsm == 2'b00 && \r
84        tx_char_idle == 1   ) begin\r
85 //     tx_uart_busy_sr[7:6] == 2'b10 && \r
86 //     tx_uart_busy == 0                 ) begin\r
87     tx_busy_jk <= 0;\r
88     if ( tx_done_jk == 1 ) begin\r
89       tx_done_char <= 1;\r
90       tx_done_jk   <= 0;\r
91     end\r
92   end \r
93 \r
94   // Queue up a binary byte to convert to ASCII as 2 nibbles for UART \r
95   if ( tx_byte_en == 1 ) begin\r
96     tx_busy_jk <= 1;\r
97     tx_fsm     <= 2'b11;\r
98     tx_byte_sr <= tx_byte_d[7:0];\r
99   end\r
100 \r
101   // Shift out a nibble when ready\r
102   if ( tx_fsm != 2'b00 && tx_uart_busy == 0 && \r
103        tx_en == 0 && tx_en_p1 == 0 ) begin\r
104     tx_en       <= 1;// Send tx_char_d[7:0] to UART \r
105     tx_fsm[1:0] <= { tx_fsm[0], 1'b0 };\r
106     tx_byte_sr  <= { tx_byte_sr[3:0], 4'd0 };// Nibble Shift\r
107   end\r
108 \r
109   // tx_char_d[7:0] is ASCII converted version of tx_nib_bin[3:0]\r
110   if ( tx_nib_bin < 4'hA ) begin\r
111     tx_char_d[7:0] <= 8'h30 + tx_nib_bin[3:0];// 0x30-0x00=0x30 (duh)\r
112   end else begin\r
113     tx_char_d[7:0] <= 8'h37 + tx_nib_bin[3:0];// 0x41-0x0A=0x37\r
114   end\r
115 \r
116   // Was a "\n" queued up? Send it now\r
117   if ( tx_done_char == 1 ) begin\r
118     tx_char_d[7:0] <= `ascii_lf; // aka "\n"\r
119     tx_en          <= 1;\r
120   end\r
121 \r
122   if ( reset == 1 ) begin\r
123     tx_busy_jk <= 0;\r
124     tx_done_jk <= 0;\r
125     tx_fsm     <= 2'b00;\r
126   end \r
127 end\r
128   assign tx_nib_bin = tx_byte_sr[7:4];\r
129 \r
130 \r
131 endmodule // mesa_byte2ascii\r