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