https://blackmesalabs.wordpress.com/2016/10/24/sump2-96-msps-logic-analyzer-for-22/
[BML_sump2] / sump2 / source / mesa_byte2ascii.v
diff --git a/sump2/source/mesa_byte2ascii.v b/sump2/source/mesa_byte2ascii.v
new file mode 100644 (file)
index 0000000..2465e38
--- /dev/null
@@ -0,0 +1,131 @@
+/* ****************************************************************************\r
+-- Source file: mesa_byte2ascii.v                \r
+-- Date:        October 4, 2015\r
+-- Author:      khubbard\r
+-- Description: Convert a binary byte to two ASCII nibs for UART transmission.\r
+--              Must handshake with both byte sender and UART for busy status.\r
+--              Also tracks a tx_done signal that queues up a "\n" to be sent.\r
+-- Language:    Verilog-2001\r
+-- Simulation:  Mentor-Modelsim \r
+-- Synthesis:   Lattice     \r
+-- License:     This project is licensed with the CERN Open Hardware Licence\r
+--              v1.2.  You may redistribute and modify this project under the\r
+--              terms of the CERN OHL v.1.2. (http://ohwr.org/cernohl).\r
+--              This project is distributed WITHOUT ANY EXPRESS OR IMPLIED\r
+--              WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY QUALITY\r
+--              AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL\r
+--              v.1.2 for applicable Conditions.\r
+--\r
+-- Revision History:\r
+-- Ver#  When      Who      What\r
+-- ----  --------  -------- ---------------------------------------------------\r
+-- 0.1   10.04.15  khubbard Creation\r
+-- ***************************************************************************/\r
+`default_nettype none // Strictly enforce all nets to be declared\r
+\r
+module mesa_byte2ascii\r
+(\r
+  input  wire         clk,\r
+  input  wire         reset,\r
+  input  wire [7:0]   tx_byte_d,\r
+  input  wire         tx_byte_en,\r
+  output wire         tx_byte_busy,\r
+  input  wire         tx_byte_done,\r
+  output reg  [7:0]   tx_char_d,\r
+  output wire         tx_char_en,\r
+  input  wire         tx_char_busy,\r
+  input  wire         tx_char_idle\r
+);// module mesa_byte2ascii\r
+\r
+  reg           tx_done_jk;\r
+  reg           tx_done_char;\r
+  reg           tx_en;\r
+  reg           tx_en_p1;\r
+  reg           tx_busy_jk;\r
+  reg  [1:0]    tx_fsm;\r
+  reg  [7:0]    tx_byte_sr;\r
+  wire          tx_uart_busy;\r
+  reg           tx_uart_busy_p1;\r
+  reg  [7:0]    tx_uart_busy_sr;\r
+  wire [3:0]    tx_nib_bin;\r
+\r
+  `define ascii_lf       8'H0a\r
\r
+  assign tx_uart_busy = tx_char_busy;\r
+  assign tx_char_en   = tx_en;\r
+  assign tx_byte_busy = tx_busy_jk | tx_byte_en;\r
+\r
+//-----------------------------------------------------------------------------\r
+// When a binary byte is sent to transmit, immediately assert tx_busy\r
+// then convert 1of2 nibbles to ASCII and send out until byte is done.\r
+// If tx_done asserts, wait for tx_busy to drop and then send a "\n".\r
+// 0x30 = "0"\r
+// 0x39 = "9"\r
+// 0x41 = "A"\r
+// 0x46 = "F"\r
+// 0x61 = "a"\r
+// 0x66 = "f"\r
+//-----------------------------------------------------------------------------\r
+always @ ( posedge clk ) begin : proc_tx  \r
+  tx_done_char    <= 0;\r
+  tx_en           <= 0;\r
+  tx_en_p1        <= tx_en;\r
+  tx_uart_busy_p1 <= tx_uart_busy;\r
+  tx_uart_busy_sr <= { tx_uart_busy_sr[6:0], tx_uart_busy };\r
+\r
+  // Remember that the transmission was complete to queue up a "\n"\r
+  if ( tx_byte_done == 1 ) begin\r
+    tx_done_jk <= 1;\r
+  end\r
+\r
+  // Deassert tx_busy_jk on falling edge of UART busy when no more nibbles\r
+//if ( tx_fsm == 2'b00 && tx_uart_busy_p1 == 1 && tx_uart_busy == 0 ) begin\r
+  if ( tx_fsm == 2'b00 && \r
+       tx_char_idle == 1   ) begin\r
+//     tx_uart_busy_sr[7:6] == 2'b10 && \r
+//     tx_uart_busy == 0                 ) begin\r
+    tx_busy_jk <= 0;\r
+    if ( tx_done_jk == 1 ) begin\r
+      tx_done_char <= 1;\r
+      tx_done_jk   <= 0;\r
+    end\r
+  end \r
+\r
+  // Queue up a binary byte to convert to ASCII as 2 nibbles for UART \r
+  if ( tx_byte_en == 1 ) begin\r
+    tx_busy_jk <= 1;\r
+    tx_fsm     <= 2'b11;\r
+    tx_byte_sr <= tx_byte_d[7:0];\r
+  end\r
+\r
+  // Shift out a nibble when ready\r
+  if ( tx_fsm != 2'b00 && tx_uart_busy == 0 && \r
+       tx_en == 0 && tx_en_p1 == 0 ) begin\r
+    tx_en       <= 1;// Send tx_char_d[7:0] to UART \r
+    tx_fsm[1:0] <= { tx_fsm[0], 1'b0 };\r
+    tx_byte_sr  <= { tx_byte_sr[3:0], 4'd0 };// Nibble Shift\r
+  end\r
+\r
+  // tx_char_d[7:0] is ASCII converted version of tx_nib_bin[3:0]\r
+  if ( tx_nib_bin < 4'hA ) begin\r
+    tx_char_d[7:0] <= 8'h30 + tx_nib_bin[3:0];// 0x30-0x00=0x30 (duh)\r
+  end else begin\r
+    tx_char_d[7:0] <= 8'h37 + tx_nib_bin[3:0];// 0x41-0x0A=0x37\r
+  end\r
+\r
+  // Was a "\n" queued up? Send it now\r
+  if ( tx_done_char == 1 ) begin\r
+    tx_char_d[7:0] <= `ascii_lf; // aka "\n"\r
+    tx_en          <= 1;\r
+  end\r
+\r
+  if ( reset == 1 ) begin\r
+    tx_busy_jk <= 0;\r
+    tx_done_jk <= 0;\r
+    tx_fsm     <= 2'b00;\r
+  end \r
+end\r
+  assign tx_nib_bin = tx_byte_sr[7:4];\r
+\r
+\r
+endmodule // mesa_byte2ascii\r