20f9cc68db9eaf474c8704170da17049fb7fb923
[SCSI2SD.git] / software / SCSI2SD / SCSI2SD.cydsn / scsiTarget / scsiTarget.v
1 \r
2 //`#start header` -- edit after this line, do not edit this line\r
3 //      Copyright (C) 2013 Michael McMaster <michael@codesrc.com>\r
4 //\r
5 //      This file is part of SCSI2SD.\r
6 //\r
7 //      SCSI2SD is free software: you can redistribute it and/or modify\r
8 //      it under the terms of the GNU General Public License as published by\r
9 //      the Free Software Foundation, either version 3 of the License, or\r
10 //      (at your option) any later version.\r
11 //\r
12 //      SCSI2SD is distributed in the hope that it will be useful,\r
13 //      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 //      GNU General Public License for more details.\r
16 //\r
17 //      You should have received a copy of the GNU General Public License\r
18 //      along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
19 `include "cypress.v"\r
20 //`#end` -- edit above this line, do not edit this line\r
21 // Generated on 10/16/2013 at 00:01\r
22 // Component: scsiTarget\r
23 module scsiTarget (\r
24         output [7:0] DBx_out, // Active High, connected to SCSI bus via inverter\r
25         output  REQ, // Active High, connected to SCSI bus via inverter\r
26         input   nACK, // Active LOW, connected directly to SCSI bus.\r
27         input  [7:0] nDBx_in, // Active LOW, connected directly to SCSI bus.\r
28         input   IO, // Active High, set by CPU via status register.\r
29         input   nRST, // Active LOW, connected directly to SCSI bus.\r
30         input   clk\r
31 );\r
32 \r
33 \r
34 //`#start body` -- edit after this line, do not edit this line\r
35 \r
36 /////////////////////////////////////////////////////////////////////////////\r
37 // Force Clock Sync\r
38 /////////////////////////////////////////////////////////////////////////////\r
39 // The udb_clock_enable primitive component is used to indicate that the input\r
40 // clock must always be synchronous and if not implement synchronizers to make\r
41 // it synchronous.\r
42 wire op_clk;\r
43 cy_psoc3_udb_clock_enable_v1_0 #(.sync_mode(`TRUE)) ClkSync\r
44 (\r
45     .clock_in(clk),\r
46     .enable(1'b1),\r
47     .clock_out(op_clk)\r
48 );\r
49 \r
50 /////////////////////////////////////////////////////////////////////////////\r
51 // FIFO Status Register\r
52 /////////////////////////////////////////////////////////////////////////////\r
53 // Status Register: scsiTarget_StatusReg__STATUS_REG\r
54 //     Bit 0: Tx FIFO not full\r
55 //     Bit 1: Rx FIFO not empty\r
56 //     Bit 2: Tx FIFO empty\r
57 //     Bit 3: Rx FIFO full\r
58 //\r
59 // TX FIFO Register: scsiTarget_scsiTarget_u0__F0_REG\r
60 // RX FIFO Register: scsiTarget_scsiTarget_u0__F1_REG\r
61 // Use with CY_GET_REG8 and CY_SET_REG8\r
62 wire f0_bus_stat;   // Tx FIFO not full\r
63 wire f0_blk_stat;       // Tx FIFO empty\r
64 wire f1_bus_stat;       // Rx FIFO not empty\r
65 wire f1_blk_stat;       // Rx FIFO full\r
66 cy_psoc3_status #(.cy_force_order(1), .cy_md_select(8'h00)) StatusReg\r
67 (\r
68     /* input          */  .clock(op_clk),\r
69     /* input  [04:00] */  .status({4'b0, f1_blk_stat, f0_blk_stat, f1_bus_stat, f0_bus_stat})\r
70 );\r
71 \r
72 /////////////////////////////////////////////////////////////////////////////\r
73 // CONSTANTS\r
74 /////////////////////////////////////////////////////////////////////////////\r
75 localparam IO_WRITE = 1'b1;\r
76 localparam IO_READ = 1'b0;\r
77 \r
78 /////////////////////////////////////////////////////////////////////////////\r
79 // STATE MACHINE\r
80 /////////////////////////////////////////////////////////////////////////////\r
81 // TX States:\r
82 // IDLE\r
83 //     Wait for an entry in the FIFO, and for the SCSI Initiator to be ready\r
84 // FIFOLOAD\r
85 //     Load F0 into A0. Feed (old) A0 into the ALU SRCA.\r
86 // TX\r
87 //     Load data register from PO. PO is fed by A0 going into the ALU via SRCA\r
88 //     A0 must remain unchanged.\r
89 // DESKEW_INIT\r
90 //     DBx output signals will be output in this state\r
91 //     Load deskew clock count into A0 from D0\r
92 // DESKEW\r
93 //     DBx output signals will be output in this state\r
94 //     Wait for the SCSI deskew time of 55ms. (DEC A0).\r
95 //     A1 must be fed into SRCA, so PO is now useless.\r
96 // READY\r
97 //     REQ and DBx output signals will be output in this state\r
98 //     Wait for acknowledgement from the SCSI initiator.\r
99 // RX\r
100 //     Dummy state for flow control.\r
101 //     REQ signal will be output in this state\r
102 //     PI enabled for input into ALU "PASS" operation, storing into F1.\r
103 //\r
104 // RX States:\r
105 // IDLE\r
106 //     Wait for a dummy "enabling" entry in the input FIFO, and wait for space\r
107 //     in output the FIFO, and for the SCSI Initiator to be ready\r
108 // FIFOLOAD\r
109 //     Load F0 into A0.\r
110 //     The input FIFO is used to control the number of bytes we attempt to\r
111 //     read from the SCSI bus.\r
112 // READY\r
113 //     REQ signal will be output in this state\r
114 //     Wait for the initiator to send a byte on the SCSI bus.\r
115 // RX\r
116 //     REQ signal will be output in this state\r
117 //     PI enabled for input into ALU "PASS" operation, storing into F1.\r
118 \r
119 \r
120 localparam STATE_IDLE = 3'b000;\r
121 localparam STATE_FIFOLOAD = 3'b001;\r
122 localparam STATE_TX = 3'b010;\r
123 localparam STATE_DESKEW_INIT = 3'b011;\r
124 localparam STATE_DESKEW = 3'b100;\r
125 // This state intentionally not used.\r
126 localparam STATE_READY = 3'b110;\r
127 localparam STATE_RX = 3'b111;\r
128 \r
129 // state selects the datapath register.\r
130 reg[2:0] state;\r
131 \r
132 // Data being read/written from/to the SCSI bus\r
133 reg[7:0] data;\r
134 \r
135 // Set by the datapath zero detector (z1). High when A1 counts down to zero.\r
136 // D1 set to constant by .d1_init_a(4) (55ns at 66MHz)\r
137 wire deskewComplete;\r
138 \r
139 // Parallel input to the datapath SRCA.\r
140 // Selected for input through to the ALU if CFB EN bit set for the datapath\r
141 // state and enabled by PI DYN bit in CFG15-14\r
142 wire[7:0] pi;\r
143 \r
144 // Parallel output from the selected SRCA value (A0 or A1) to the ALU.\r
145 wire[7:0] po;\r
146 \r
147 // Set true to trigger storing A1 into F1.\r
148 wire fifoStore;\r
149 \r
150 // Set Output Pins\r
151 assign REQ = state[1] & state[2]; // STATE_READY & STATE_RX\r
152 assign DBx_out[7:0] = data;\r
153 assign pi[7:0] = ~nDBx_in[7:0]; // Invert active low scsi bus\r
154 assign fifoStore = (state == STATE_RX) ? 1'b1 : 1'b0;\r
155 \r
156 always @(posedge op_clk) begin\r
157         case (state)\r
158                 STATE_IDLE:\r
159                 begin\r
160                         // Check that SCSI initiator is ready, and input FIFO is not empty,\r
161                         // and output FIFO is not full.\r
162                         // Note that output FIFO is unused in TX mode.\r
163                         if (nACK & !f0_blk_stat && !f1_blk_stat)\r
164                                 state <= STATE_FIFOLOAD;\r
165                         else\r
166                                 state <= STATE_IDLE;\r
167 \r
168                         // Clear our output pins\r
169                         data <= 8'b0;\r
170                 end\r
171 \r
172                 STATE_FIFOLOAD:\r
173                         state <= IO == IO_WRITE ? STATE_TX : STATE_READY;\r
174 \r
175                 STATE_TX:\r
176                 begin\r
177                         state <= STATE_DESKEW_INIT;\r
178                         data <= po;\r
179                 end\r
180 \r
181                 STATE_DESKEW_INIT: state <= STATE_DESKEW;\r
182 \r
183                 STATE_DESKEW:\r
184                         if(deskewComplete) state <= STATE_READY;\r
185                         else state <= STATE_DESKEW;\r
186 \r
187                 STATE_READY:\r
188                         //if ((IO == IO_WRITE) & ~nACK) state <= STATE_IDLE;\r
189                         //else if ((IO == IO_READ) & ~nACK) state <= STATE_RX;\r
190                         if (~nACK) state <= STATE_RX;\r
191                         else state <= STATE_READY;\r
192 \r
193                 STATE_RX: state <= STATE_IDLE;\r
194 \r
195                 default: state <= STATE_IDLE;\r
196         endcase\r
197 end\r
198 \r
199 cy_psoc3_dp #(.d1_init(3), \r
200 .cy_dpconfig(\r
201 {\r
202     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
203     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
204     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
205     `CS_CMP_SEL_CFGA, /*CFGRAM0:         IDLE*/\r
206     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
207     `CS_SHFT_OP_PASS, `CS_A0_SRC___F0, `CS_A1_SRC_NONE,\r
208     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
209     `CS_CMP_SEL_CFGA, /*CFGRAM1:         FIFO Load*/\r
210     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
211     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
212     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
213     `CS_CMP_SEL_CFGA, /*CFGRAM2:         TX*/\r
214     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
215     `CS_SHFT_OP_PASS, `CS_A0_SRC___D0, `CS_A1_SRC_NONE,\r
216     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
217     `CS_CMP_SEL_CFGA, /*CFGRAM3:         DESKEW INIT*/\r
218     `CS_ALU_OP__DEC, `CS_SRCA_A0, `CS_SRCB_D0,\r
219     `CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,\r
220     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
221     `CS_CMP_SEL_CFGA, /*CFGRAM4:         DESKEW*/\r
222     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
223     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
224     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
225     `CS_CMP_SEL_CFGA, /*CFGRAM5:   Not used*/\r
226     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
227     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
228     `CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
229     `CS_CMP_SEL_CFGA, /*CFGRAM6:         READY*/\r
230     `CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,\r
231     `CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,\r
232     `CS_FEEDBACK_ENBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,\r
233     `CS_CMP_SEL_CFGA, /*CFGRAM7:         RX*/\r
234     8'hFF, 8'h00,  /*CFG9:            */\r
235     8'hFF, 8'hFF,  /*CFG11-10:            */\r
236     `SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,\r
237     `SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,\r
238     `SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,\r
239     `SC_SI_A_DEFSI, /*CFG13-12:            */\r
240     `SC_A0_SRC_ACC, `SC_SHIFT_SL, `SC_PI_DYN_EN,\r
241     1'h0, `SC_FIFO1_ALU, `SC_FIFO0_BUS,\r
242     `SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,\r
243     `SC_FB_NOCHN, `SC_CMP1_NOCHN,\r
244     `SC_CMP0_NOCHN, /*CFG15-14:            */\r
245     10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,\r
246     `SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,\r
247     `SC_WRK16CAT_DSBL /*CFG17-16:            */\r
248 }\r
249 )) datapath(\r
250         /*  input                   */  .reset(1'b0),\r
251         /*  input                   */  .clk(op_clk),\r
252         /*  input   [02:00]         */  .cs_addr(state),\r
253         /*  input                   */  .route_si(1'b0),\r
254         /*  input                   */  .route_ci(1'b0),\r
255         /*  input                   */  .f0_load(1'b0),\r
256         /*  input                   */  .f1_load(fifoStore),\r
257         /*  input                   */  .d0_load(1'b0),\r
258         /*  input                   */  .d1_load(1'b0),\r
259         /*  output                  */  .ce0(),\r
260         /*  output                  */  .cl0(),\r
261         /*  output                  */  .z0(deskewComplete),\r
262         /*  output                  */  .ff0(),\r
263         /*  output                  */  .ce1(),\r
264         /*  output                  */  .cl1(),\r
265         /*  output                  */  .z1(),\r
266         /*  output                  */  .ff1(),\r
267         /*  output                  */  .ov_msb(),\r
268         /*  output                  */  .co_msb(),\r
269         /*  output                  */  .cmsb(),\r
270         /*  output                  */  .so(),\r
271         /*  output                  */  .f0_bus_stat(f0_bus_stat),\r
272         /*  output                  */  .f0_blk_stat(f0_blk_stat),\r
273         /*  output                  */  .f1_bus_stat(f1_bus_stat),\r
274         /*  output                  */  .f1_blk_stat(f1_blk_stat),\r
275         \r
276         /* input                    */  .ci(1'b0),     // Carry in from previous stage\r
277         /* output                   */  .co(),         // Carry out to next stage\r
278         /* input                    */  .sir(1'b0),    // Shift in from right side\r
279         /* output                   */  .sor(),        // Shift out to right side\r
280         /* input                    */  .sil(1'b0),    // Shift in from left side\r
281         /* output                   */  .sol(),        // Shift out to left side\r
282         /* input                    */  .msbi(1'b0),   // MSB chain in\r
283         /* output                   */  .msbo(),       // MSB chain out\r
284         /* input [01:00]            */  .cei(2'b0),    // Compare equal in from prev stage\r
285         /* output [01:00]           */  .ceo(),        // Compare equal out to next stage\r
286         /* input [01:00]            */  .cli(2'b0),    // Compare less than in from prv stage\r
287         /* output [01:00]           */  .clo(),        // Compare less than out to next stage\r
288         /* input [01:00]            */  .zi(2'b0),     // Zero detect in from previous stage\r
289         /* output [01:00]           */  .zo(),         // Zero detect out to next stage\r
290         /* input [01:00]            */  .fi(2'b0),     // 0xFF detect in from previous stage\r
291         /* output [01:00]           */  .fo(),         // 0xFF detect out to next stage\r
292         /* input [01:00]            */  .capi(2'b0),   // Software capture from previous stage\r
293         /* output [01:00]           */  .capo(),       // Software capture to next stage\r
294         /* input                    */  .cfbi(1'b0),   // CRC Feedback in from previous stage\r
295         /* output                   */  .cfbo(),       // CRC Feedback out to next stage\r
296         /* input [07:00]            */  .pi(pi),     // Parallel data port\r
297         /* output [07:00]           */  .po(po)          // Parallel data port\r
298 );\r
299 //`#end` -- edit above this line, do not edit this line\r
300 endmodule\r
301 //`#start footer` -- edit after this line, do not edit this line\r
302 //`#end` -- edit above this line, do not edit this line\r
303 \r
304 \r
305 \r
306 \r
307 \r
308 \r
309 \r
310 \r
311 \r
312 \r
313 \r
314 \r
315 \r
316 \r
317 \r
318 \r
319 \r
320 \r
321 \r
322 \r