x393  1.0
FPGAcodeforElphelNC393camera
ahci_fis_transmit.v
Go to the documentation of this file.
1 
26 `timescale 1ns/1ps
27 
29  parameter PREFETCH_ALWAYS = 0,
30  parameter READ_REG_LATENCY = 2, // 0 if reg_rdata is available with reg_re/reg_addr, 2 with re/regen
31 // parameter READ_CT_LATENCY = 1, // 0 if reg_rdata is available with reg_re/reg_addr, 2 with re/regen
32  parameter READ_CT_LATENCY = 2, // 0 if reg_rdata is available with reg_re/reg_addr, 2 with re/regen
33  parameter ADDRESS_BITS = 10 // number of memory address bits - now fixed. Low half - RO/RW/RWC,RW1 (2-cycle write), 2-nd just RW (single-cycle)
34 
35 )(
36  input hba_rst, // @posedge mclk - when port is reset (even COMINIT)?
37  input mclk, // for command/status
38  input pcmd_st_cleared, // ~= hba_rst?
39  // Command pulses to execute states
40  input fetch_cmd, // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
41  // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
42  input cfis_xmit, // transmit command (wait for dma_ct_busy == 0)
43  input dx_xmit, // send FIS header DWORD, (just 0x46), then forward DMA data
44  // transmit until error, 2048DWords or pDmaXferCnt
45  input atapi_xmit, // trasmit ATAPI command FIS
46 
47 
48  output reg done, // for fetch_cmd - dma_start, for *_xmit - xmit_ok, xmit_err, syncesc_recv or xrdy_collision
49  output reg busy,
50 
51  input clearCmdToIssue, // From CFIS:SUCCESS
52  output pCmdToIssue, // AHCI port variable
53 // output dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output
54 // output reg fetch_cmd_busy, // does not include prefetching CT - now just use busy/done
55 
56 // Should wait for xmit_ok? Timeout? Timeout will be handled by software, so just wait for OK or some error
57  input xmit_ok, // FIS transmission acknowledged OK
58  input xmit_err, //
59  input syncesc_recv, // These two inputs interrupt transmit
61  output [ 2:0] dx_err, // bit 0 - syncesc_recv, 1 - R_ERR (was xmit_err), 2 - collision (valid @ xmit_err and later, reset by new command)
62 
63  output [15:0] ch_prdtl, // Physical region descriptor table length (in entries, 0 is 0)
64  output ch_c, // Clear busy upon R_OK for this FIS
65  output ch_b, // Built-in self test command
66  output ch_r, // reset - may need to send SYNC escape before this command
67  output ch_p, // prefetchable - only used with non-zero PRDTL or ATAPI bit set
68  output ch_w, // Write: system memory -> device
69  output ch_a, // ATAPI: 1 means device should send PIO setup FIS for ATAPI command
70  output [4:0] ch_cfl, // length of the command FIS in DW, 0 means none. 0 and 1 - illegal,
71  // maximal is 16 (0x10)
72  output reg [11:0] dwords_sent, // number of DWORDs transmitted (up to 2048)
73 
74  // register memory interface
75  output reg [ADDRESS_BITS-1:0] reg_addr,
76  output [ 1:0] reg_re,
77  input [31:0] reg_rdata,
78 
79  // ahci_fis_receive interface
80  input [31:2] xfer_cntr, // transfer counter in words for both DMA (31 bit) and PIO (lower 15 bits), updated after decr_dwc
81  input xfer_cntr_zero, // transfer counter was not set
82 
83 
84  output dma_ctba_ld, // load command table address from
85  output dma_start, // start processing command table, reset prdbc (next cycle after dma_ctba_ld, bits prdtl valid)
86  output dma_dev_wr, // write to device (valid at start)
87  input dma_ct_busy, // dma module is busy reading command table from the system memory
88  // issue dma_prd_start same time as dma_start if prefetch enabled, otherwise with cfis_xmit
89  output reg dma_prd_start, // at or after cmd_start - enable reading PRD/data (if any) ch_prdtl should be valid, twice - OK
90  output reg dma_cmd_abort, // try to abort a command
91 
92  // reading out command table data from DMA module
93  output reg [ 4:0] ct_addr, // DWORD address
94  output [ 1:0] ct_re, // [0] - re, [1] - regen
95  input [31:0] ct_data, //
96 
97  // DMA (memory -> device) interface
98  input [31:0] dma_out, // 32-bit data from the DMA module, HBA -> device port
99  input dma_dav, // at least one dword is ready to be read from DMA module
100  output dma_re, // read dword from DMA module to the output register
101  input last_h2d_data,// last dword in dma_out
102 
103  // Data System memory or FIS -> device
104  output reg [31:0] todev_data, // 32-bit data from the system memory to HBA (dma data)
105  output reg [ 1:0] todev_type, // 0 - data, 1 - FIS head, 2 - FIS LAST)
106  output todev_valid, // output register full
107  input todev_ready // send FIFO has room for data (>= 8? dwords)
108 
109  ,output [9:0] debug_01
110 
111  // Add a possiblity to flush any data to FIFO if error was detected after data went there?
112 );
113  localparam CLB_OFFS32 = 'h200; // # In the second half of the register space (0x800..0xbff - 1KB)
114  localparam DATA_FIS = 32'h46;
116  reg dma_en_r;
118  wire [1:0] fis_data_type;
119  wire [31:0] fis_data_out;
120 
122  // for fis_data_valid - longer latency
123 // wire fis_out_w = !dma_en_r && fis_data_valid && todev_ready;
125 /// wire dma_re_w = dma_en_r && dma_dav && todev_ready && (!todev_full_r || !watch_prd_end_w);
126 
127  reg [15:0] ch_prdtl_r;
128  reg ch_c_r;
129  reg ch_b_r;
130  reg ch_r_r;
131  reg ch_p_r;
132  reg ch_w_r;
133  reg ch_a_r;
134  reg [4:0] ch_cmd_len_r;
135  reg [4:0] cfis_acmd_left_r; // number of DWORDS in CFIS or ACMD area of the command table left to be fetched from ahci_dma module BRAM
136  // For CFIS this register is set from ch_cmd_len_r, for ACMD - from the xfer_cntr input
137  // (stored in the ahci_fis_receive module)
138  reg [4:0] cfis_acmd_left_out_r; // Same, just with latency of the data available from the ahci_dma module
139 
140 // reg [31:7] ch_ctba_r;
142  wire reg_re_w; // combined conditions to read register memory
143 /// wire reg_stb = reg_re_r[READ_REG_LATENCY];
144 /// wire reg_stb = reg_re_r[READ_REG_LATENCY-1];
145  wire pre_reg_stb = reg_re_r[READ_REG_LATENCY-1] && !reg_re_r[READ_REG_LATENCY]; // only first, to make running 1
146  reg [3:0] fetch_chead_r;
147  reg [3:0] fetch_chead_stb_r;
148  wire chead_done_w = fetch_chead_stb_r[2]; // done fetching command header
149  reg chead_bsy; // busy reading command header
150  reg chead_bsy_re; // busy sending read command header
152 // reg fetch_ct_r;
156 // reg anc_fis_r; // This is ATAPI FIS, not Command FIS
157 
158  wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy_r; // dma_ct_busy no gaps with fetch_cmd_busy
160 
161  wire ct_re_w; // next cycle will be ct_re;
163 
165 
168 
169  reg [11:0] dx_dwords_left;
170  reg dx_fis_pend_r; // waiting to send first DWORD of the H2D data transfer
171  wire dx_dma_last_w; // sending last data word
173  reg [ 2:0] dx_err_r;
176 // wire done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error
177  // dma_start ends 'fetch_cmd'
178  wire done_w = xmit_ok_r || ((|dx_err_r) && dx_busy_r) || dma_start; // done on last transmit or error
179 
181 
182  // now ahci_dma watches for the last data DWORD and generates last_h2d_data, so transmission will end if either of xfer counter or DMA data (defined by total prd size)
183  // if xfer_cntr wazs 0, it will never be decremented and never equal to 1, will not generate last)
184 // reg xfer_cntr_is_set;
185 // reg watch_prd_end;
186 // wire masked_last_h2d_data = xfer_cntr_not_set && last_h2d_data; // otherwise use xfer counter to find FIS end
187 // wire watch_prd_end_w = masked_last_h2d_data || watch_prd_end; // Maybe not needed - just use watch_prd_end
188 
189 // reg [1:0] was_dma_re; // previous values of dma_re
190 // reg [2:0] was_dma_ndav; // inverted/masked previous values of dma_dav
191 // wire send_last_w = was_dma_ndav[2];
192  assign todev_valid = todev_full_r;
193 // assign todev_valid = todev_full_r && (!watch_prd_end_w || dma_dav || send_last_w);
194  assign dma_re = dma_re_w;
195  assign reg_re = reg_re_r[1:0];
196 
197  assign ch_prdtl = ch_prdtl_r;
198  assign ch_c = ch_c_r;
199  assign ch_b = ch_b_r;
200  assign ch_r = ch_r_r;
201  assign ch_p = ch_p_r;
202  assign ch_w = ch_w_r;
203  assign ch_a = ch_a_r;
204 // assign ch_cfl = cfis_acmd_left_r;
205  assign ch_cfl = ch_cmd_len_r;
206  assign reg_re_w = fetch_cmd || chead_bsy_re;
207  assign dma_ctba_ld = fetch_chead_stb_r[2];
208  assign dma_start = fetch_chead_stb_r[3]; // next cycle after dma_ctba_ld
209  assign pCmdToIssue = pCmdToIssue_r;
210 // assign dmaCntrZero = dmaCntrZero_r;
211  assign ct_re = ct_re_r[1:0];
212 /// assign fis_data_valid = ct_stb; // no wait write to output register 'todev_data', ct_re_r[0] is throttled according to FIFO room availability
213  // What else to wait for when
214  assign fis_data_valid = ct_stb || (!dma_ct_busy && dx_fis_pend_r); // no wait write to output register 'todev_data', ct_re_r[0] is throttled according to FIFO room availability
215 
216 /// assign ct_re_w = todev_ready && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0])); // Later add more sources
217  assign ct_re_w = todev_ready && acfis_xmit_busy_r && ((cfis_acmd_left_r[4:1] != 0) || (cfis_acmd_left_r[0] && !ct_re_r[0])); // Later add more sources
218  //
219  assign fis_dw_last = (cfis_acmd_left_out_r == 1);
221 
222  assign fis_data_out = ({32{dx_fis_pend_r}} & DATA_FIS) | ({32{ct_stb}} & ct_data) ;
223  assign dx_dma_last_w = dma_en_r && dma_re_w && ((dx_dwords_left[11:0] == 1) || last_h2d_data);
224 
225  assign dx_err = dx_err_r;
226  assign dma_dev_wr = ch_w_r;
227 /// assign write_or_w = (dma_en_r?(dma_dav && todev_ready ):fis_data_valid); // do not fill the buffer if FIFO is not ready for DMA,
228 /// assign write_or_w = (dma_en_r?(dma_dav && todev_ready && (!todev_full_r || !watch_prd_end_w)):fis_data_valid); // do not fill the buffer if FIFO is not ready for DMA,
229  assign write_or_w = dma_re_w || fis_data_valid;
230 
231 // When watching for FIS end, do not fill/use output register in the same cycle
232 
233  reg [3:0] dbg_was_ct_re_r;
235 
236 
237 
238  always @ (posedge mclk) begin
239  // Mutliplex between DMA and FIS output to the output routed to transmit FIFO
240  // Count bypassing DMA dwords to generate FIS_last condition?
241  if (hba_rst || pcmd_st_cleared) todev_full_r <= 0;
242  else if (write_or_w) todev_full_r <= 1; // do not fill the buffer if FIFO is not ready
243  else if (todev_ready) todev_full_r <= 0;
244 
246 
247  if (hba_rst) todev_type <= 3; // invalid? - no, now first and last word in command FIS (impossible?)
248  else if (write_or_w) todev_type <= dma_en_r? {dx_dma_last_w , 1'b0} : fis_data_type;
249  // Read 3 DWORDs from the command header
250 
251  if (hba_rst) fetch_chead_r <= 0; // running 1
252  else fetch_chead_r <= {fetch_chead_r[2:0], fetch_cmd};
253 
254  if (hba_rst) fetch_chead_stb_r <= 0;
256 
257  if (hba_rst) chead_bsy <= 0;
258  else if (fetch_cmd) chead_bsy <= 1;
259  else if (chead_done_w) chead_bsy <= 0;
260 
261  if (hba_rst) chead_bsy_re <= 0;
262  else if (fetch_cmd) chead_bsy_re <= 1;
263  else if (fetch_chead_r[1]) chead_bsy_re <= 0; // read 3 dwords
264 
265  if (hba_rst) reg_re_r <= 0; // [0] -> reg_re output
266  else reg_re_r <= {reg_re[1:0], reg_re_w};
267 
268  if (fetch_cmd) reg_addr <= CLB_OFFS32; // there will be more conditions
269  else if (reg_re_r[0]) reg_addr <= reg_addr + 1;
270 
271  // save command header data to registers
272  if (fetch_chead_stb_r[0]) begin
273  ch_prdtl_r <= reg_rdata[31:16];
274  ch_c_r <= reg_rdata[ 10];
275  ch_b_r <= reg_rdata[ 9];
276  ch_r_r <= reg_rdata[ 8];
277  ch_p_r <= reg_rdata[ 7];
278  ch_w_r <= reg_rdata[ 6];
279 // ch_a_r <= reg_rdata[ 5];
280  ch_cmd_len_r<= reg_rdata[ 4: 0];
281  end
282 //ch_a
283  if (hba_rst || atapi_xmit) ch_a_r <= 0;
284  else if (fetch_chead_stb_r[0]) ch_a_r <= reg_rdata[ 5];
285 
286  if (hba_rst) pCmdToIssue_r <= 0;
287  else if (chead_done_w) pCmdToIssue_r <= 1;
288  else if (clearCmdToIssue) pCmdToIssue_r <= 0;
289 
291  else if (fetch_cmd) fetch_cmd_busy_r <= 1;
292  else if (dma_start) fetch_cmd_busy_r <= 0;
293 
294  //CFIS/ATAPI common
295 
296  // fetch and send command/atapi FIS
298  else if (cfis_xmit || atapi_xmit) acfis_xmit_pend_r <= 1;
299 
301 
303  else if (acfis_xmit_start_r) acfis_xmit_busy_r <= 1;
304  else if (acfis_xmit_end) acfis_xmit_busy_r <= 0;
305 
306  if (cfis_xmit) cfis_acmd_left_r <= ch_cmd_len_r[ 4: 0]; // Will assume that there is room for ...
307  else if (atapi_xmit) cfis_acmd_left_r <= (|xfer_cntr[31:4]) ? 5'h4 : {3'b0,xfer_cntr[3:2]};
309 
310  // Counting CFIS/ATAPI FIS dwords sent to TL
313 
314  if (hba_rst || acfis_xmit_start_w) ct_re_r <= 0;
315  else ct_re_r <= {ct_re_r[READ_CT_LATENCY-1:0], ct_re_w};
316 
317  if (cfis_xmit) ct_addr <= 0;
318  else if (atapi_xmit) ct_addr <= 'h10; // start of ATAPI area
319 // else if (cfis_acmd_left_r[0]) ct_addr <= ct_addr + 1;
320  else if (ct_re_r[0]) ct_addr <= ct_addr + 1;
321 //
322  // first/last dword in FIS
323  if (!acfis_xmit_busy_r) fis_dw_first <= 1;
324  else if (ct_stb) fis_dw_first <= 0;
325 
326  //TODO: update xfer length, prdtl (only after R_OK) - yes, do it outside
327 
328  if (dx_xmit) dx_dwords_left[11:0] <= (xfer_cntr_zero || (|xfer_cntr[31:13])) ? 12'h800 : {1'b0,xfer_cntr[12:2]};
329  else if (dma_re_w) dx_dwords_left[11:0] <= dx_dwords_left[11:0] - 1;
330 
331  if (dx_xmit) dwords_sent <= 0;
332  else if (dma_re_w) dwords_sent <= dwords_sent + 1;
333 
334  // send FIS header
336  else if (dx_xmit) dx_fis_pend_r <= 1;
337 
338  if (hba_rst || dx_dma_last_w || (|dx_err_r) || pcmd_st_cleared) dma_en_r <= 0;
339  else if (dx_fis_pend_r && write_or_w) dma_en_r <= 1;
340 
341  // Abort on transmit errors
342  if (hba_rst || any_cmd_start) dx_err_r[0] <= 0;
343  else if (syncesc_recv) dx_err_r[0] <= 1;
344 
345  if (hba_rst || any_cmd_start) dx_err_r[1] <= 0;
346  else if (xmit_err) dx_err_r[1] <= 1;
347 
348  if (hba_rst || any_cmd_start) dx_err_r[2] <= 0;
349  else if (xrdy_collision) dx_err_r[2] <= 1;
350 
351  if (hba_rst || pcmd_st_cleared) dx_busy_r <= 0; // sending CFIS, AFIS or data FIS (until error or R_OK)
352  else if (dx_xmit || acfis_xmit_start_r) dx_busy_r <= 1;
353  else if (xmit_ok || (|dx_err_r)) dx_busy_r <= 0;
354 
355  dma_prd_start <= (dma_start && (PREFETCH_ALWAYS || ch_p_r || !ch_w_r)) || // device read may prefetch just prd addresses
356  (dx_fis_pend_r && write_or_w); // enable PRD read now (if it was not already done)
357 
358  if (hba_rst) done <= 0;
359  else done <= done_w;
360 
361  if (hba_rst || pcmd_st_cleared) busy <= 0;
362  else if (any_cmd_start) busy <= 1;
363  else if (done_w) busy <= 0;
364 
365  if (hba_rst) xmit_ok_r <= 0;
366  else xmit_ok_r <= dx_busy_r && !(|dx_err_r) && xmit_ok;
367 
368  dma_cmd_abort <= done_w && (|dx_err_r);
369 
372 
373  end
374 
375  assign debug_01 = {dx_fis_pend_r, ct_re_r, ct_re_w, cfis_acmd_left_r}; // 1,2,5
376 // assign debug_01 = {acfis_xmit_start_w, acfis_xmit_pend_r, dma_ct_busy, fetch_cmd_busy_r, ct_re_w, dbg_was_cfis_acmd_left_r}; // 1,2,5
377 // wire acfis_xmit_start_w = (cfis_xmit || atapi_xmit || acfis_xmit_pend_r) && !dma_ct_busy && !fetch_cmd_busy_r; // dma_ct_busy no gaps with fetch_cmd_busy
378 
379 
380 endmodule
381 
reg [11:0] 13324dwords_sent
reg [31:0] 13343todev_data
13354fis_data_outwire[31:0]
reg [ADDRESS_BITS-1:0] 13325reg_addr
reg [ 1:0] 13344todev_type
13367reg_re_rreg[READ_REG_LATENCY:0]
13371fetch_chead_stb_rreg[3:0]
reg [ 4:0] 13336ct_addr
13382ct_re_rreg[READ_CT_LATENCY:0]
13366cfis_acmd_left_out_rreg[4:0]
13386dx_dwords_leftreg[11:0]
13396dbg_was_cfis_acmd_left_rreg[4:0]