Use DMA for SCSI and SD card transfers for a massive performance boost.
[SCSI2SD-V6.git] / software / SCSI2SD / SCSI2SD.cydsn / scsiTarget / scsiTarget.v
index 91dbc273775f8cb22a24bbc3ab875e03b4762843..5d46c5ac691673c65aebc251d596176f3771759e 100755 (executable)
@@ -27,7 +27,9 @@ module scsiTarget (
        input  [7:0] nDBx_in, // Active LOW, connected directly to SCSI bus.\r
        input   IO, // Active High, set by CPU via status register.\r
        input   nRST, // Active LOW, connected directly to SCSI bus.\r
-       input   clk\r
+       input   clk,\r
+       output tx_intr,\r
+       output rx_intr\r
 );\r
 \r
 \r
@@ -47,28 +49,6 @@ cy_psoc3_udb_clock_enable_v1_0 #(.sync_mode(`TRUE)) ClkSync
     .clock_out(op_clk)\r
 );\r
 \r
-/////////////////////////////////////////////////////////////////////////////\r
-// FIFO Status Register\r
-/////////////////////////////////////////////////////////////////////////////\r
-// Status Register: scsiTarget_StatusReg__STATUS_REG\r
-//     Bit 0: Tx FIFO not full\r
-//     Bit 1: Rx FIFO not empty\r
-//     Bit 2: Tx FIFO empty\r
-//     Bit 3: Rx FIFO full\r
-//\r
-// TX FIFO Register: scsiTarget_scsiTarget_u0__F0_REG\r
-// RX FIFO Register: scsiTarget_scsiTarget_u0__F1_REG\r
-// Use with CY_GET_REG8 and CY_SET_REG8\r
-wire f0_bus_stat;   // Tx FIFO not full\r
-wire f0_blk_stat;      // Tx FIFO empty\r
-wire f1_bus_stat;      // Rx FIFO not empty\r
-wire f1_blk_stat;      // Rx FIFO full\r
-cy_psoc3_status #(.cy_force_order(1), .cy_md_select(8'h00)) StatusReg\r
-(\r
-    /* input          */  .clock(op_clk),\r
-    /* input  [04:00] */  .status({4'b0, f1_blk_stat, f0_blk_stat, f1_bus_stat, f0_bus_stat})\r
-);\r
-\r
 /////////////////////////////////////////////////////////////////////////////\r
 // CONSTANTS\r
 /////////////////////////////////////////////////////////////////////////////\r
@@ -80,7 +60,7 @@ localparam IO_READ = 1'b0;
 /////////////////////////////////////////////////////////////////////////////\r
 // TX States:\r
 // IDLE\r
-//     Wait for an entry in the FIFO, and for the SCSI Initiator to be ready\r
+//     Wait for the SCSI Initiator to be ready\r
 // FIFOLOAD\r
 //     Load F0 into A0. Feed (old) A0 into the ALU SRCA.\r
 // TX\r
@@ -91,11 +71,12 @@ localparam IO_READ = 1'b0;
 //     Load deskew clock count into A0 from D0\r
 // DESKEW\r
 //     DBx output signals will be output in this state\r
-//     Wait for the SCSI deskew time of 55ms. (DEC A0).\r
+//     Wait for the SCSI deskew time of 55ns. (DEC A0).\r
 //     A1 must be fed into SRCA, so PO is now useless.\r
 // READY\r
 //     REQ and DBx output signals will be output in this state\r
-//     Wait for acknowledgement from the SCSI initiator.\r
+//     Wait for acknowledgement from the SCSI initiator\r
+//     Wait for space in output fifo\r
 // RX\r
 //     Dummy state for flow control.\r
 //     REQ signal will be output in this state\r
@@ -103,8 +84,8 @@ localparam IO_READ = 1'b0;
 //\r
 // RX States:\r
 // IDLE\r
-//     Wait for a dummy "enabling" entry in the input FIFO, and wait for space\r
-//     in output the FIFO, and for the SCSI Initiator to be ready\r
+//     Wait for a dummy "enabling" entry in the input FIFO,\r
+//     and for the SCSI Initiator to be ready\r
 // FIFOLOAD\r
 //     Load F0 into A0.\r
 //     The input FIFO is used to control the number of bytes we attempt to\r
@@ -112,6 +93,7 @@ localparam IO_READ = 1'b0;
 // READY\r
 //     REQ signal will be output in this state\r
 //     Wait for the initiator to send a byte on the SCSI bus.\r
+//     Wait for space in output fifo\r
 // RX\r
 //     REQ signal will be output in this state\r
 //     PI enabled for input into ALU "PASS" operation, storing into F1.\r
@@ -152,6 +134,38 @@ assign DBx_out[7:0] = data;
 assign pi[7:0] = ~nDBx_in[7:0]; // Invert active low scsi bus\r
 assign fifoStore = (state == STATE_RX) ? 1'b1 : 1'b0;\r
 \r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// FIFO Status Register\r
+/////////////////////////////////////////////////////////////////////////////\r
+// Status Register: scsiTarget_StatusReg__STATUS_REG\r
+//     Bit 0: Tx FIFO not full\r
+//     Bit 1: Rx FIFO not empty\r
+//     Bit 2: Tx FIFO empty\r
+//     Bit 3: Rx FIFO full\r
+//     Bit 4: TX Complete. Fifos empty and idle.\r
+//\r
+// TX FIFO Register: scsiTarget_scsiTarget_u0__F0_REG\r
+// RX FIFO Register: scsiTarget_scsiTarget_u0__F1_REG\r
+// Use with CY_GET_REG8 and CY_SET_REG8\r
+wire f0_bus_stat;   // Tx FIFO not full\r
+wire f0_blk_stat;      // Tx FIFO empty\r
+wire f1_bus_stat;      // Rx FIFO not empty\r
+wire f1_blk_stat;      // Rx FIFO full\r
+wire txComplete = f0_blk_stat && (state == STATE_IDLE);\r
+cy_psoc3_status #(.cy_force_order(1), .cy_md_select(8'h00)) StatusReg\r
+(\r
+    /* input          */  .clock(op_clk),\r
+    /* input  [04:00] */  .status({3'b0, txComplete, f1_blk_stat, f0_blk_stat, f1_bus_stat, f0_bus_stat})\r
+);\r
+\r
+// DMA outputs\r
+assign tx_intr = f0_bus_stat;\r
+assign rx_intr = f1_bus_stat;\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// State machine\r
+/////////////////////////////////////////////////////////////////////////////\r
 always @(posedge op_clk) begin\r
        case (state)\r
                STATE_IDLE:\r
@@ -160,7 +174,7 @@ always @(posedge op_clk) begin
                        // and output FIFO is not full.\r
                        // Note that output FIFO is unused in TX mode.\r
                        if (!nRST) state <= STATE_IDLE;\r
-                       else if (nACK & !f0_blk_stat && !f1_blk_stat)\r
+                       else if (nACK & !f0_blk_stat)\r
                                state <= STATE_FIFOLOAD;\r
                        else\r
                                state <= STATE_IDLE;\r
@@ -191,68 +205,74 @@ always @(posedge op_clk) begin
 \r
                STATE_READY:\r
                        if (!nRST) state <= STATE_IDLE;\r
-                       else if (~nACK) state <= STATE_RX;\r
+                       else if (~nACK && ((IO == IO_WRITE) || !f1_blk_stat)) state <= STATE_RX;\r
                        else state <= STATE_READY;\r
 \r
-               STATE_RX: state <= STATE_IDLE;\r
+               STATE_RX: // same code here as for the IDLE state, as we make\r
+                       // a quick run back to the next byte if possible.\r
+                       if (!nRST) state <= STATE_IDLE;\r
+                       else if (nACK & !f0_blk_stat)\r
+                               state <= STATE_FIFOLOAD;\r
+                       else\r
+                               state <= STATE_IDLE;\r
 \r
                default: state <= STATE_IDLE;\r
        endcase\r
 end\r
 \r
-// D1 is used for the deskew count.\r
+// D0 is used for the deskew count.\r
 // The data output is valid during the DESKEW_INIT phase as well,\r
 // so we subtract 1.\r
-// D1 = [0.000000055 / (1 / clk)] - 1\r
-cy_psoc3_dp #(.d1_init(1), \r
+// D0 = [0.000000055 / (1 / clk)] - 1\r
+cy_psoc3_dp #(.d0_init(2), \r
 .cy_dpconfig(\r
 {\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM0:         IDLE*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM0:          IDLE*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC___F0, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM1:         FIFO Load*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM1:          FIFO Load*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM2:         TX*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM2:          TX*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC___D0, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM3:         DESKEW INIT*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM3:          DESKEW INIT*/\r
     `CS_ALU_OP__DEC, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM4:         DESKEW*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM4:          DESKEW*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM5:   Not used*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM5:    Not used*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM6:         READY*/\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM6:          READY*/\r
     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
     `CS_FEEDBACK_ENBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
-    `CS_CMP_SEL_CFGA, /*CFGRAM7:         RX*/\r
-    8'hFF, 8'h00,  /*CFG9:            */\r
-    8'hFF, 8'hFF,  /*CFG11-10:            */\r
+    `CS_CMP_SEL_CFGA, /*CFGRAM7:          RX*/\r
+    8'hFF, 8'h00,  /*CFG9:             */\r
+    8'hFF, 8'hFF,  /*CFG11-10:             */\r
     `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,\r
     `SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,\r
     `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,\r
-    `SC_SI_A_DEFSI, /*CFG13-12:            */\r
+    `SC_SI_A_DEFSI, /*CFG13-12:             */\r
     `SC_A0_SRC_ACC, `SC_SHIFT_SL, `SC_PI_DYN_EN,\r
     1'h0, `SC_FIFO1_ALU, `SC_FIFO0_BUS,\r
     `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,\r
     `SC_FB_NOCHN, `SC_CMP1_NOCHN,\r
-    `SC_CMP0_NOCHN, /*CFG15-14:            */\r
+    `SC_CMP0_NOCHN, /*CFG15-14:             */\r
     10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,\r
     `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,\r
-    `SC_WRK16CAT_DSBL /*CFG17-16:            */\r
+    `SC_WRK16CAT_DSBL /*CFG17-16:             */\r
 }\r
 )) datapath(\r
         /*  input                   */  .reset(1'b0),\r
@@ -308,3 +328,4 @@ cy_psoc3_dp #(.d1_init(1),
 endmodule\r
 //`#start footer` -- edit after this line, do not edit this line\r
 //`#end` -- edit above this line, do not edit this line\r
+\r