https://blackmesalabs.wordpress.com/2016/10/24/sump2-96-msps-logic-analyzer-for-22/
[BML_sump2] / sump2 / source / mesa_decode.v
diff --git a/sump2/source/mesa_decode.v b/sump2/source/mesa_decode.v
new file mode 100755 (executable)
index 0000000..d95072f
--- /dev/null
@@ -0,0 +1,250 @@
+/* ****************************************************************************\r
+-- (C) Copyright 2015 Kevin M. Hubbard @ Black Mesa Labs\r
+-- Source file: mesa_decode.v                \r
+-- Date:        October 4, 2015   \r
+-- Author:      khubbard\r
+-- Language:    Verilog-2001 \r
+-- Description: The Mesa Bus decoder. Mesa Bus is a byte-pipe much like a \r
+--              8b10b SERDES pipe. It supports sending packetized streams of\r
+--              serialized bytes to multiple targets on a single serial bus.\r
+--              This implementation uses UART serial, but the protocol is \r
+--              portable and may be used over SERDES or a synchronous bit,\r
+--              nibble or byte wide streams. \r
+--              This block decodes packets and routes them to both\r
+--              dowstream slots and the internal sub-slots for this slot.\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
+--\r
+-- Example:\r
+--    .."FF".."FF"."F0123401[56]" : \r
+--        0xFF = Bus Idle ( NULLs )\r
+--  B0    0xF0 = New Bus Cycle to begin ( Nibble and bit orientation )\r
+--  B1    0x12 = Slot Number, 0xFF = Broadcast all slots, 0xFE = NULL Dest\r
+--  B2    0x3  = Sub-Slot within the chip (0-0xF)\r
+--        0x4  = Command Nibble for Sub-Slot ( Specific to that SubSlot )\r
+--  B3    0x01 = Number of Payload Bytes (0-255)\r
+--        0x56 = The Payload ( 1 Byte in this example, up to 255 total )\r
+--\r
+--   Slot Numbering 0x00-0xFF:\r
+--     0x00 - 0xFD : Physical Slots 0-253\r
+--     0xF0 - 0xFD : Reserved\r
+--     0xFE        : Nobody slot ( NULL )\r
+--     0xFF        : Broadcast to 0x00-0xEF\r
+--\r
+--   SubSlot Numbering 0x0-0xF:\r
+--     0x0 - 0x7   : User SubSlots ( 0x0 is nominally a 32bit PCI local bus )\r
+--                    0x0 = LB Bus Write\r
+--                    0x1 = LB Bus Read\r
+--                    0x2 = LB Bus Write Repeat ( same address )\r
+--                    0x3 = LB Bus Read Repeat  ( same address )\r
+--     0x8 - 0xB   : Scope Probe CH1-CH4 Mux Selects\r
+--                    0x0 - 0xF : 1 of 16 signal sets to observe. 0x0 nom OFF\r
+--     0xE         : FPGA PROM Access\r
+--                   Commands:\r
+--                    0x0 = LB Bus Write\r
+--                    0x1 = LB Bus Read\r
+--                    0x2 = LB Bus Write Repeat ( same address )\r
+--                    0x3 = LB Bus Read Repeat  ( same address )\r
+--     0xF         :  Mesa Control : Power and Pin Control\r
+--                    Commands:\r
+--\r
+--                    0x0 = Ro pin is MesaBus Ro Readback     ( Default )\r
+--                    0x1 = Ro pin is MesaBus Wi loopback\r
+--                    0x2 = Ro pin is MesaBus Interrupt\r
+--                    0x3 = Ro pin is user defined output function\r
+--                    0x4 = Ri pin is MesaBus Input           ( Default )\r
+--                    0x5 = Ri pin is disabled\r
+--                    0x6 = Wo pin is MesaBus Output          ( Default )\r
+--                    0x7 = Wo pin is disabled\r
+--\r
+--                    0x8 = RESERVED\r
+--                    0x9 = RESERVED\r
+--                    0xA = Report Device ID\r
+--                    0xB = Reset Core \r
+--                    0xC = Clear Baud Lock\r
+--                    0xD = Power Off     - Clock Trees Disabled\r
+--                    0xE = Boot to Slot-1 Bootloader (Default)\r
+--                    0xF = Boot to Slot-2 User Image\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_decode\r
+(\r
+  input  wire         clk,\r
+  input  wire         reset,\r
+  input  wire [3:0]   rx_in_d,\r
+  input  wire         rx_in_rdy,\r
+  output wire [7:0]   rx_out_d,\r
+  output wire         rx_out_rdy,\r
+  output wire [7:0]   rx_loc_d,\r
+  output wire         rx_loc_rdy,\r
+  output wire         rx_loc_start,\r
+  output wire         rx_loc_stop\r
+); // module mesa_decode\r
+\r
+\r
+  reg           lbracket_jk;\r
+  reg           passthru_jk;\r
+  reg           broadcst_jk;\r
+  reg           payload_jk;\r
+  reg           process_jk;\r
+\r
+  reg           packet_jk;\r
+  reg           packet_jk_p1;\r
+  reg [7:0]     byte_sr;\r
+  reg           byte_pingpong;\r
+  reg           rx_in_rdy_p1;\r
+  reg           byte_rdy;\r
+  reg           byte_rdy_p1;\r
+  reg [3:0]     byte_cnt;\r
+  reg [7:0]     byte_loc;\r
+  reg [7:0]     byte_out;\r
+  reg [7:0]     payload_cnt;\r
+  reg           packet_done;\r
+\r
+  reg           loc_start;\r
+  reg [7:0]     loc_slot;\r
+  reg [3:0]     loc_subslot;\r
+  reg [3:0]     loc_command;\r
+  reg [7:0]     loc_payload;\r
+\r
+  assign rx_out_d     = byte_out[7:0];\r
+  assign rx_out_rdy   = byte_rdy_p1;\r
+  assign rx_loc_d     = byte_loc[7:0];\r
+  assign rx_loc_rdy   = byte_rdy_p1;\r
+  assign rx_loc_start = loc_start;\r
+  assign rx_loc_stop  = packet_done;\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+// Shift a nibble into a byte shift register.  The 1st 0xF0 received when NOT\r
+// currently in a packet determines the phasing for byte within nibble stream.\r
+//-----------------------------------------------------------------------------\r
+always @ ( posedge clk ) begin : proc_nib_in \r
+ rx_in_rdy_p1  <= rx_in_rdy;\r
+ if ( rx_in_rdy == 1 ) begin\r
+   byte_sr[7:4]  <= byte_sr[3:0];\r
+   byte_sr[3:0]  <= rx_in_d[3:0];\r
+   byte_pingpong <= ~ byte_pingpong;\r
+ end\r
+ if ( packet_jk == 0 ) begin\r
+   byte_pingpong <= 0;\r
+ end\r
+ if ( reset == 1 ) begin\r
+   byte_sr[7:0]  <= 8'hFF;\r
+ end\r
+end\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+// Decode and direct : Packet begins on a 0xF0 byte - which provides for both \r
+// bit and nibble alignment as bus sits idle at 0xFF.\r
+//-----------------------------------------------------------------------------\r
+always @ ( posedge clk ) begin : proc_byte_in \r
+ byte_rdy     <= 0;\r
+ packet_jk_p1 <= packet_jk;\r
+\r
+ if ( rx_in_rdy_p1 == 1 ) begin\r
+   if ( byte_sr == 8'hF0 && packet_jk == 0 ) begin\r
+     packet_jk <= 1;\r
+     byte_rdy  <= 1;\r
+   end\r
+   if ( packet_jk == 1 && byte_pingpong == 0 ) begin\r
+     byte_rdy <= 1;\r
+   end\r
+ end\r
+\r
+ if ( reset == 1 || packet_done == 1 ) begin\r
+   packet_jk <= 0;\r
+ end\r
+end // proc_byte_in\r
+\r
+\r
+//-----------------------------------------------------------------------------\r
+//              B0 B1   B2               B3\r
+//  0xFF,0xFF,0xF0,Slot,Sub-Slot+Command,Payload_Len,{ payload },\r
+//\r
+// A Packet is a 4-byte header followed by an optional n-Byte Payload.\r
+// The Byte after the 1st 0xF0 determines the destination slot.\r
+//   slot 0xFF is broadcast and is forwarded untouched as 0xFF.\r
+//   slot 0xFE is null and is forwarded untouched as 0xFE.\r
+//   slot 0x00 is for this slot and is forwarded as 0xFE.\r
+//   slot 0x01-0xFD is decremented by 1 and forwarded\r
+// The 4th Byte determines the length of the payload. If 0, the packet is done.\r
+// otherwise, packet continues for n-Bytes to deliver the payload. A 0xF0 \r
+// following a completed packet indicates start of next packet.\r
+//-----------------------------------------------------------------------------\r
+always @ ( posedge clk ) begin : proc_header\r
+ byte_rdy_p1 <= byte_rdy;\r
+ packet_done <= 0;\r
+ loc_start   <= 0;\r
+ if ( byte_rdy == 1 ) begin\r
+   // Count the Packet Header Bytes from 1-4 and stop\r
+   if ( byte_cnt != 4'h4 ) begin\r
+     byte_cnt <= byte_cnt + 1;\r
+   end\r
+   if ( byte_cnt == 4'h3 ) begin\r
+     payload_cnt <= byte_sr[7:0];\r
+     if ( byte_sr == 8'd0 ) begin\r
+       packet_done <= 1;// No Payload - done immediately\r
+     end\r
+   end\r
+   if ( byte_cnt == 4'h4 ) begin\r
+     payload_cnt <= payload_cnt - 1;\r
+   end\r
+   if ( byte_cnt == 4'h4 && payload_cnt == 8'd1 ) begin\r
+     packet_done <= 1;\r
+   end\r
+\r
+   if ( byte_cnt == 4'h0 ) begin\r
+    loc_start <= 1;\r
+   end\r
+   if ( byte_cnt == 4'h1 ) begin\r
+    loc_slot <= byte_sr[7:0];\r
+   end\r
+   if ( byte_cnt == 4'h2 ) begin\r
+    loc_subslot <= byte_sr[7:4];\r
+    loc_command <= byte_sr[3:0];\r
+   end\r
+   if ( byte_cnt == 4'h3 ) begin\r
+    loc_payload <= byte_sr[7:0];\r
+   end\r
+\r
+   // Decode the Slot Number, Decrement when needed. Route to Local and Ext\r
+   if ( byte_cnt == 4'h1 ) begin\r
+     if ( byte_sr == 8'hFF ||\r
+          byte_sr == 8'hFE ) begin\r
+       byte_loc <= byte_sr[7:0];// 0xFF Broadcast and 0xFE null go to everybody\r
+       byte_out <= byte_sr[7:0];\r
+     end else if ( byte_sr != 8'h00 ) begin\r
+       byte_loc <= 8'hFE;\r
+       byte_out <= byte_sr[7:0] - 1;// Decrement the Slot Number as non-zero\r
+     end else begin\r
+       byte_loc <= byte_sr[7:0];// Slot Number is 0x00, so this slot gets it\r
+       byte_out <= 8'hFE;       // Downstream slots get 0xFE instead\r
+     end\r
+   end else begin\r
+     byte_loc <= byte_sr[7:0];\r
+     byte_out <= byte_sr[7:0];\r
+   end\r
+ end // if ( byte_rdy == 1 ) begin\r
+\r
+ if ( packet_jk == 0 ) begin\r
+   byte_cnt    <= 4'd0;\r
+   payload_cnt <= 8'd0;\r
+ end\r
+end // proc_header\r
+\r
+\r
+endmodule // mesa_decode\r