Commit 84a54d4f authored by Andrey Filippov's avatar Andrey Filippov

debugging: passed request/receive 'identify'

parent 3f3c3b83
......@@ -204,7 +204,7 @@ module ahci_dma (
wire cmd_done_hclk;
wire ct_done_mclk;
reg [3:0] afi_alen;
wire afi_wcount_many = !afi_wcount[7] && !(afi_wcount[6:4]);
wire afi_wcount_many = !afi_wcount[7] && !(&afi_wcount[6:4]);
reg data_next_burst;
......@@ -310,8 +310,10 @@ module ahci_dma (
end
// afi_rd_ctl <= { afi_rd_ctl[0],(ct_busy_r[0] || prd_rd_busy) && ((|afi_rcount[7:SAFE_RD_BITS]) || (afi_rvalid && !(|afi_rd_ctl)))};
wire debug_01 = ct_busy_r[0] || prd_rd_busy ;
wire debug_02 =|afi_rcount[7:SAFE_RD_BITS];
wire debug_03 = (afi_rvalid && !(|afi_rd_ctl));
always @ (posedge hclk) begin
prd_start_hclk_r <= prd_start_hclk;
......@@ -379,7 +381,7 @@ module ahci_dma (
if (afi_rd_ctl[0] && is_prd_addr && (int_data_addr[0])) data_irq <= afi_rdata[63];
if (afi_rd_ctl[0] && is_prd_addr && (int_data_addr[0])) wcount[21:1] <= afi_rdata[37:17];
if (afi_rd_ctl[0] && is_prd_addr && (int_data_addr[0])) wcount[21:1] <= afi_rdata[53:33];
wcount_set <= afi_rd_ctl[0] && is_prd_addr && (int_data_addr[0]);
......@@ -406,10 +408,10 @@ module ahci_dma (
// generate busy for PRD table entry read
if (hrst) prd_rd_busy <= 0;
else if (prd_rd_busy) prd_rd_busy <= 1;
// else if (prd_rd_busy) prd_rd_busy <= 1;
else if (raddr_prd_rq && axi_set_raddr_ready) prd_rd_busy <= 1;
else if (wcount_set) prd_rd_busy <= 0;
if (cmd_start_hclk) dev_wr_hclk <= dev_wr_mclk; // 1: memory -> device, 0: device -> memory
prd_wr <= wcount_set && !dev_wr_hclk;
......
......@@ -80,14 +80,15 @@ module ahci_dma_wr_fifo#(
reg [63:16] fifo_do_prev; // only 48 bits are needed
reg [(1<<ADDRESS_BITS)-1:0] fifo_full; // set in write clock domain
reg [(1<<ADDRESS_BITS)-1:0] fifo_nempty;// set in read clock domain
wire fifo_wr = (din_avail && din_rdy) || (waddr[0] && flush_mclk); // flush may add extra write of junk
wire fifo_wr = en_fifo_wr && ((din_avail && din_rdy) || (waddr[0] && flush_mclk)); // flush may add extra write of junk
// wire fifo_rd;
wire [(1<<ADDRESS_BITS)-1:0] fifo_full2 = {fifo_full[0],fifo_full[ADDRESS_NUM-1:1]};
wire [(1<<ADDRESS_BITS)-1:0] fifo_full2 = {~fifo_full[0],fifo_full[ADDRESS_NUM-1:1]};
reg hrst_mclk;
reg fifo_dav; // @hclk
reg fifo_dav2; // @hclk
reg fifo_dav2; // @hclk - ??? at least two are available?
reg fifo_half_mclk; // Half Fifo is empty, OK to write
wire [63:0] fifo_do = {fifo1_ram [raddr[ADDRESS_BITS:1]], fifo0_ram [raddr[ADDRESS_BITS:1]]};
/// wire [63:0] fifo_do = {fifo1_ram [raddr[ADDRESS_BITS:1]], fifo0_ram [raddr[ADDRESS_BITS:1]]};
wire [63:0] fifo_do = {fifo1_ram [raddr[ADDRESS_BITS-1:0]], fifo0_ram [raddr[ADDRESS_BITS-1:0]]};
wire dout_we_w;
reg [1:0] dout_we_r;
......@@ -125,7 +126,8 @@ module ahci_dma_wr_fifo#(
wire fifo_out_ready = en_fifo_rd && (!need_fifo || (fifo_dav && (fifo_dav2 || !fifo_rd_r)));
assign flush_hclk = is_last_prd && !flushing && !nfp[1] && last_qword && waddr[0]; // waddr[0] - other clock domain, but OK here,
/// assign flush_hclk = is_last_prd && !flushing && !nfp[1] && last_qword && waddr[0]; // waddr[0] - other clock domain, but OK here,
assign flush_hclk = busy && is_last_prd && !flushing && !nfp[1] && last_qword && waddr[0]; // waddr[0] - other clock domain, but OK here,
// it was last 1->0 before previous FIFO read. flush_hclk will only be generated for odd number of dwords
assign din_rdy = en_fifo_wr && fifo_half_mclk;
......@@ -146,17 +148,20 @@ module ahci_dma_wr_fifo#(
if (hrst || init) raddr <= 0;
else if (fifo_rd) raddr <= raddr + 1;
else if (fifo_rd) raddr <= raddr + 1; // increment for 64-bit words
// reg [ADDRESS_BITS : 0] raddr; // 1 extra bit
if (hrst || init) fifo_nempty <= {{(ADDRESS_NUM>>1){1'b0}},{(ADDRESS_NUM>>1){1'b1}}};// 8'b00001111
else if (fifo_rd && raddr[0]) fifo_nempty <= {fifo_nempty[ADDRESS_NUM-2:0],raddr[ADDRESS_BITS] ^ raddr[ADDRESS_BITS-1]};
/// else if (fifo_rd && raddr[0]) fifo_nempty <= {fifo_nempty[ADDRESS_NUM-2:0],raddr[ADDRESS_BITS] ^ raddr[ADDRESS_BITS-1]};
else if (fifo_rd) fifo_nempty <= {fifo_nempty[ADDRESS_NUM-2:0],~raddr[ADDRESS_BITS] ^ raddr[ADDRESS_BITS-1]};
fifo_dav <= !init && en_fifo_rd && (fifo_full [raddr[ADDRESS_BITS:1]] ^ raddr[ADDRESS_BITS]);
fifo_dav2 <= !init && en_fifo_rd && (fifo_full2[raddr[ADDRESS_BITS:1]]);
/// fifo_dav <= !init && en_fifo_rd && (fifo_full [raddr[ADDRESS_BITS:1]] ^ raddr[ADDRESS_BITS]);
fifo_dav <= !init && en_fifo_rd && (fifo_full [raddr[ADDRESS_BITS-1:0]] ^ raddr[ADDRESS_BITS]);
/// fifo_dav2 <= !init && en_fifo_rd && (fifo_full2[raddr[ADDRESS_BITS:1]]); //?^ raddr[ADDRESS_BITS]); // FIXME
fifo_dav2 <= !init && en_fifo_rd && (fifo_full2[raddr[ADDRESS_BITS-1:0]] ^ raddr[ADDRESS_BITS]); //?^ raddr[ADDRESS_BITS]); // FIXME
if (fifo_rd) fifo_do_prev[63:16] <= fifo_do[63:16];
......@@ -261,14 +266,16 @@ module ahci_dma_wr_fifo#(
else if (fifo_wr) waddr <= waddr + 1;
if (hrst_mclk || init_mclk) fifo_full <= 0;
else if (fifo_wr) fifo_full <= {fifo_full[ADDRESS_NUM-2:0], waddr[ADDRESS_BITS+1]};
/// else if (fifo_wr) fifo_full <= {fifo_full[ADDRESS_NUM-2:0], waddr[ADDRESS_BITS+1]};
else if (fifo_wr && waddr[0]) fifo_full <= {fifo_full[ADDRESS_NUM-2:0], ~waddr[ADDRESS_BITS+1]};
fifo_half_mclk <= fifo_nempty [waddr[ADDRESS_BITS:1]] ^ waddr[ADDRESS_BITS+1];
fifo_half_mclk <= en_fifo_wr && fifo_nempty [waddr[ADDRESS_BITS:1]] ^ waddr[ADDRESS_BITS+1];
if (fifo_wr && !waddr[0]) fifo0_ram[waddr[ADDRESS_BITS:1]] <= din;
if (fifo_wr && waddr[0]) fifo1_ram[waddr[ADDRESS_BITS:1]] <= din;
fifo_nempty_mclk <= (fifo_full [raddr[ADDRESS_BITS:1]] ^ raddr[ADDRESS_BITS]); // only valid after read is stopped
/// fifo_nempty_mclk <= (fifo_full [raddr[ADDRESS_BITS:1]] ^ raddr[ADDRESS_BITS]); // only valid after read is stopped
fifo_nempty_mclk <= (fifo_full [raddr[ADDRESS_BITS-1:0]] ^ raddr[ADDRESS_BITS]); // only valid after read is stopped
end
......
......@@ -192,7 +192,7 @@ localparam DATA_TYPE_ERR = 3;
reg update_sig_r;
// reg update_pio_r;
reg update_prdbc_r;
reg get_fis_busy_r;
reg [1:0] get_fis_busy_r;
reg [7:0] pio_es_r; // value of PIO E_Status
......@@ -207,9 +207,9 @@ localparam DATA_TYPE_ERR = 3;
reg fis_first_flushing_r;
// Forward data to DMA (dev->mem) engine
assign dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err;
assign dma_in_valid = dma_in && dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err;
// Will also try to skip to the end of too long FIS
assign dma_skipping_extra = (fis_extra_r || too_long_err) && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready ;
assign dma_skipping_extra = dma_in && (fis_extra_r || too_long_err) && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready ;
assign dma_in_stop = dma_in && data_in_ready && (hba_data_in_type != DATA_TYPE_DMA); // ||
......@@ -225,7 +225,7 @@ localparam DATA_TYPE_ERR = 3;
assign tfd_err = tf_err_sts[15:8];
assign xfer_cntr = xfer_cntr_r[31:2];
assign get_fis_busy = get_fis_busy_r;
assign get_fis_busy = get_fis_busy_r[0];
// assign data_in_dwords = data_out_dwords_r;
assign data_in_dwords = data_in_dwords_r;
......@@ -293,7 +293,7 @@ localparam DATA_TYPE_ERR = 3;
else if (get_fis) fis_rec_run <= 1;
else if (is_fis_end && data_in_ready) fis_rec_run <= 0;
if (hba_rst) dwords_over <= 0;
if (hba_rst ||get_fis) dwords_over <= 0;
else if (wreg_we_r && !(|fis_dcount)) dwords_over <= 1;
if (hba_rst) wreg_we_r <= 0;
......@@ -301,14 +301,17 @@ localparam DATA_TYPE_ERR = 3;
fis_end_r <= {fis_end_r[0], fis_end_w};
if (hba_rst) get_fis_busy_r <= 0;
else if (get_fis) get_fis_busy_r <= 1;
else if (too_long_err || fis_end_w) get_fis_busy_r <= 0;
if (hba_rst) get_fis_busy_r[0] <= 0;
else if (get_fis) get_fis_busy_r[0] <= 1;
else if (too_long_err || fis_end_w) get_fis_busy_r[0] <= 0;
get_fis_done <= get_fis_busy_r && (too_long_err || fis_end_w);
get_fis_busy_r[1] <=get_fis_busy_r[0];
// if (hba_rst || get_fis) fis_first_vld <= 0;
if (hba_rst || fis_end_w) fis_first_vld <= 0; // is_FIS_HEAD stays on longer than just get_fis
get_fis_done <= get_fis_busy_r[0] && (too_long_err || fis_end_w);
/// if (hba_rst || get_fis) fis_first_vld <= 0;
/// if (hba_rst || fis_end_w) fis_first_vld <= 0; // is_FIS_HEAD stays on longer than just get_fis
if (hba_rst || (|get_fis_busy_r))fis_first_vld <= 0; // is_FIS_HEAD stays on longer than just get_fis
else if (is_FIS_HEAD) fis_first_vld <= 1;
if (hba_rst || get_fis) fis_ok <= 0;
......@@ -385,7 +388,7 @@ localparam DATA_TYPE_ERR = 3;
// Maybe it is not needed if the fsm will send this pulse?
// data_in_words_apply <= dma_in_stop && (hba_data_in_type == DATA_TYPE_OK);
if (hba_rst || get_fis_busy_r) fis_first_invalid_r <= 0;
if (hba_rst || (|get_fis_busy_r)) fis_first_invalid_r <= 0;
else fis_first_invalid_r <= is_FIS_NOT_HEAD;
if (!fis_first_invalid_r) fis_first_flushing_r <= 0;
......
......@@ -661,6 +661,7 @@ task wait_ready; // @SuppressThisWarning VEditor - Used in testbench
end
endtask
task send_good_status; // @SuppressThisWarning VEditor - Used in testbench
input integer id;
input [2:0] dev_specific_status_bits;
......@@ -673,9 +674,55 @@ task send_good_status; // @SuppressThisWarning VEditor - Used in testbench
transmit_data[3] = 1;
transmit_data[4] = 0;
linkTransmitFIS(id, 5, 0, status);
// linkTransmitFIS (
end
endtask
task send_pio_setup; // @SuppressThisWarning VEditor - Used in testbench
input integer id;
input d2h; // 'D' bit: 1 - Data will be D2H, 0 - H2D
input irq; // Set I bit
input [7:0] xmit_status;
input [7:0] xmit_error;
input [7:0] xmit_e_status;
input [15:0] xfer_count;
input [ 7:0] dev;
input [23:0] lba_low; // LBA_low dword
input [23:0] lba_high; // LBA high dword
input [15:0] count; //
output integer status;
begin
transmit_data[0] = FIS_PIOS |
(d2h? 'h2000:0) |
(irq? 'h4000:0) |
(xmit_status << 16) |
(xmit_error << 24);
transmit_data[1] = {dev, lba_low};
transmit_data[2] = {8'b0,lba_high};
transmit_data[3] = {xmit_e_status, 8'b0,count};
transmit_data[4] = {16'b0, xfer_count};
linkTransmitFIS(id, 5, 0, status);
end
endtask
task send_identify_data; // @SuppressThisWarning VEditor - Used in testbench
input integer id;
output integer status;
reg [15:0] identify_data[0:255]; // SuppressThisWarning VEditor : assigned in $readmem() system task
integer i;
begin
$readmemh("input_data/identify.dat",identify_data);
transmit_data[0] = FIS_DATA;
for (i=0;i<128;i=i+1) begin
transmit_data[i+1] = {identify_data[2 * i+1], identify_data[2 * i]};
end
linkTransmitFIS(id, 129, 0, status);
end
endtask
/*
* Transmits data to a host. ~Link Transmit FSM
* Correct execution, as it shall be w/o errors from a device side. (except timeouts and data consistency, see below)
......@@ -774,7 +821,7 @@ task linkTransmitFIS; // @SuppressThisWarning VEditor - Used in testbench
// $display("[Device] LINK: Sent data = %h", transmit_data[cnt]);
DEV_TITLE = "Sent data";
DEV_DATA = transmit_data[cnt];
$display("[Device] LINK: %s = %h @%t", DEV_TITLE, DEV_DATA, $time);
$display("[Device] LINK: %s = %h (#%d) @%t", DEV_TITLE, DEV_DATA, cnt, $time);
@ (posedge clk)
rprim = linkGetPrim(0);
if (rprim == "SYNC") begin
......
......@@ -720,17 +720,44 @@ always @ (posedge clk)
`endif
`ifdef SIMULATION
always @ (posedge clk)
begin
integer sim_cnt;
always @ (posedge clk) begin
if (incom_start) begin
HOST_LINK_TITLE = "Incoming start";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
if (data_val_out) begin
// $display("[Host] LINK: From device - received data = %h @%t", data_out, $time);
HOST_LINK_TITLE = "From device - received data";
HOST_LINK_DATA = data_out;
$display("[Host] LINK: %s = %h @%t", HOST_LINK_TITLE, HOST_LINK_DATA, $time);
//`endif
$display("[Host] LINK: %s = %h (#%d)@%t", HOST_LINK_TITLE, HOST_LINK_DATA, sim_cnt, $time);
sim_cnt = sim_cnt + 1;
end
if (incom_done) begin
HOST_LINK_TITLE = "Incoming end";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
if (incom_invalidate) begin
HOST_LINK_TITLE = "Incoming invalidate";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
if (incom_sync_escape) begin
HOST_LINK_TITLE = "Incoming sync_escape";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
if (incom_ack_good) begin
HOST_LINK_TITLE = "Incoming ack_good";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
if (incom_ack_bad) begin
HOST_LINK_TITLE = "Incoming ack_bad";
$display("[Host] LINK: %s @%t", HOST_LINK_TITLE, $time);
sim_cnt = 0;
end
// if (inc_is_data) begin
// $display("[Host] LINK: From device - received raw data = %h", phy_data_in);
// end
......
......@@ -800,6 +800,13 @@ initial begin //Host
//HBA_PORT__PxIE__DHRE__MASK = 'h1;
end
function func_is_dev_identify;
input [31:0] dw;
begin
func_is_dev_identify = ((dw & 'hff) == FIS_H2DR ) && (((dw >> 16) & 'hff) == ATA_IDFY);
end
endfunction
integer status;
initial begin //Device
dev.clear_transmit_pause(0);
......@@ -812,9 +819,40 @@ initial begin //Device
5, // input [2:0] dev_specific_status_bits;
1, // input irq;
status); // output integer status;
DEVICE_TITLE = "Device sent D2H RS";
DEVICE_TITLE = "Device sent D2H FIS";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
// Wait for host requests 'identify'
@(dev.receive_id);
if (func_is_dev_identify(dev.receive_data[0])) begin
DEVICE_TITLE = "Got Identify";
$display("[Dev-TB]: %s @%t", DEVICE_TITLE, $time);
$display("[Dev-TB]: %h @%t", dev.receive_data[0], $time);
dev.send_pio_setup (67, // input integer id;
1, // input d2h; // 'D' bit: 1 - Data will be D2H, 0 - H2D
1, // input irq; // Set I bit
'h30, // input [7:0] xmit_status; // something different to check host
0, // input [7:0] xmit_error;
'h60, // input [7:0] xmit_e_status;
512, // input [15:0] xfer_count; Identify block size
0, // input [ 7:0] dev;
0, // input [23:0] lba_low; // LBA_low dword
0, // input [23:0] lba_high; // LBA high dword
0, // input [15:0] count; //
status); // output integer status;
DEVICE_TITLE = "Device sent PIOS FIS";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
dev.send_identify_data(68, // input integer id;
status); // output integer status;
DEVICE_TITLE = "Device sent Data FIS (Identify)";
$display("[Dev-TB]: %s, status = 0x%x @%t", DEVICE_TITLE, status, $time);
end else begin
DEVICE_TITLE = "Expected Identify, got else";
$display("[Dev-TB]: %s @%t", DEVICE_TITLE, $time);
$display("[Dev-TB]: %h @%t", dev.receive_data[0], $time);
end
end
initial begin
// #30000;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment