Commit e94b62c6 authored by Andrey Filippov's avatar Andrey Filippov

added modupe to abort/recover AXI HP port after SATA errors, more debugging of the hardware

parent 50ca592a
...@@ -52,87 +52,87 @@ ...@@ -52,87 +52,87 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160208095139740.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160208095139740.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name> <name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160208095350202.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name> <name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160205231700944.log</location> <location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160208095139740.log</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-phys.dcp</name> <name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160208095350202.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt-power.dcp</name> <name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160208095350202.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-opt.dcp</name> <name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160208095350202.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-place.dcp</name> <name>vivado_state/x393_sata-place.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160208095350202.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-route.dcp</name> <name>vivado_state/x393_sata-route.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160208095350202.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393_sata-synth.dcp</name> <name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160205231700944.dcp</location> <location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160208095139740.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
This diff is collapsed.
...@@ -144,7 +144,7 @@ module ahci_fsm ...@@ -144,7 +144,7 @@ module ahci_fsm
input dma_cmd_busy, // output reg (DMA engine is processing PRDs) input dma_cmd_busy, // output reg (DMA engine is processing PRDs)
/// input dma_cmd_done, // output (last PRD is over) /// input dma_cmd_done, // output (last PRD is over)
output dma_cmd_abort, // try to abort a command output dma_cmd_abort, // try to abort a command
input dma_abort_done, // if abort is not needed, will generate dma_abort_done just next cycle
// Communication with ahci_fis_receive (some are unused) // Communication with ahci_fis_receive (some are unused)
// Debug features // Debug features
...@@ -257,15 +257,20 @@ module ahci_fsm ...@@ -257,15 +257,20 @@ module ahci_fsm
// reg jump_r; // reg jump_r;
reg [2:0] fsm_jump; reg [2:0] fsm_jump;
wire fsm_next; wire fsm_next;
reg fsm_next_r; // reg fsm_next_r;
reg fsm_actions; // processing actions reg fsm_actions; // processing actions
reg fsm_act_busy; reg fsm_act_busy;
reg [1:0] fsm_transitions; // processing transitions reg [1:0] fsm_transitions; // processing transitions
reg fsm_preload; // read first sequence data (2 cycles for regen) reg fsm_preload; // read first sequence data (2 cycles for regen)
// wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions // wire [7:0] precond_w = pgm_data[17:10]; // select what to use - cond_met_w valis after precond_w, same time as conditions
// reg [7:0] conditions; // reg [7:0] conditions;
wire pre_jump_w = (|async_pend_r) ? async_ackn : |(cond_met_w & fsm_transitions[1]); // wire pre_jump_w = (|async_pend_r) ? async_ackn : |(cond_met_w & fsm_transitions[1]);
wire fsm_act_done = get_fis_done || xmit_done || (syncesc_send_pend && syncesc_send_done); wire pre_jump_w = (|async_pend_r) ? async_ackn : (cond_met_w & fsm_transitions[1]);
wire fsm_act_done = get_fis_done ||
xmit_done ||
(syncesc_send_pend && syncesc_send_done) ||
dma_abort_done ||
asynq_rq; // cominit_got || pcmd_st_cleared
wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done
wire fsm_last_act_w = pgm_data[17]; wire fsm_last_act_w = pgm_data[17];
...@@ -283,6 +288,14 @@ module ahci_fsm ...@@ -283,6 +288,14 @@ module ahci_fsm
wire phy_ready_chng_w = !hba_rst && !was_rst && (phy_ready != phy_ready_prev); wire phy_ready_chng_w = !hba_rst && !was_rst && (phy_ready != phy_ready_prev);
reg was_last_action_r; // delay last action if it was fsm_wait_act; reg was_last_action_r; // delay last action if it was fsm_wait_act;
wire fsm_transitions_w = // next will be transitions processing
(fsm_last_act_w && fsm_actions && fsm_next && !fsm_wait_act_w) ||
(fsm_act_busy && fsm_act_done && was_last_action_r);
wire conditions_ce = // copy all conditions to the register so they will not change while iterating through them
!fsm_transitions_w && !fsm_transitions[0];
assign fsm_next = (fsm_preload || (fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]) && !async_pend_r[0]; // quiet if received cominit is pending assign fsm_next = (fsm_preload || (fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]) && !async_pend_r[0]; // quiet if received cominit is pending
assign update_all = fsm_jump[0]; assign update_all = fsm_jump[0];
...@@ -344,8 +357,9 @@ module ahci_fsm ...@@ -344,8 +357,9 @@ module ahci_fsm
if (fsm_actions && fsm_next) was_last_action_r <= fsm_last_act_w; if (fsm_actions && fsm_next) was_last_action_r <= fsm_last_act_w;
if (hba_rst || pre_jump_w) fsm_transitions <= 0; if (hba_rst || pre_jump_w) fsm_transitions <= 0;
else if ((fsm_last_act_w && fsm_actions && fsm_next && !fsm_wait_act_w) || else if (fsm_transitions_w) fsm_transitions <= 1;
(fsm_act_busy && fsm_act_done && was_last_action_r) ) fsm_transitions <= 1; // else if ((fsm_last_act_w && fsm_actions && fsm_next && !fsm_wait_act_w) ||
// (fsm_act_busy && fsm_act_done && was_last_action_r) ) fsm_transitions <= 1;
else fsm_transitions <= {fsm_transitions[0],fsm_transitions[0]}; else fsm_transitions <= {fsm_transitions[0],fsm_transitions[0]};
if (hba_rst) fsm_preload <= 0; if (hba_rst) fsm_preload <= 0;
...@@ -460,6 +474,7 @@ module ahci_fsm ...@@ -460,6 +474,7 @@ module ahci_fsm
// Condition inputs may be registered if needed // Condition inputs may be registered if needed
condition_mux condition_mux_i ( condition_mux condition_mux_i (
.clk (mclk), // input .clk (mclk), // input
.ce (conditions_ce), // input
.sel (pgm_data[17:10]), // input[7:0] .sel (pgm_data[17:10]), // input[7:0]
.condition (cond_met_w), // output .condition (cond_met_w), // output
//COMPOSITE //COMPOSITE
......
...@@ -92,7 +92,9 @@ module ahci_sata_layers #( ...@@ -92,7 +92,9 @@ module ahci_sata_layers #(
input wire rxp_in, input wire rxp_in,
input wire rxn_in, input wire rxn_in,
output [31:0] debug_sata output [31:0] debug_phy,
output [31:0] debug_link
); );
localparam PHY_SPEED = 2; // SATA2 localparam PHY_SPEED = 2; // SATA2
...@@ -169,8 +171,8 @@ module ahci_sata_layers #( ...@@ -169,8 +171,8 @@ module ahci_sata_layers #(
wire d2h_fifo_wr = ll_d2h_valid || fis_over_r; // fis_over_r will push FIS end to FIFO wire d2h_fifo_wr = ll_d2h_valid || fis_over_r; // fis_over_r will push FIS end to FIFO
reg h2d_pending; // HBA started sending FIS to fifo reg h2d_pending; // HBA started sending FIS to fifo
wire [31:0] debug_phy; // wire [31:0] debug_phy;
wire [31:0] debug_link; // wire [31:0] debug_link;
wire rxelsfull; wire rxelsfull;
wire rxelsempty; wire rxelsempty;
...@@ -184,7 +186,7 @@ module ahci_sata_layers #( ...@@ -184,7 +186,7 @@ module ahci_sata_layers #(
// assign debug_sata = {debug_link[31:4],debug_phy[3:0]} ; // // assign debug_sata = {debug_link[31:4],debug_phy[3:0]} ; //
// assign debug_sata = {debug_link[31:8],debug_phy[7:0]} ; // // assign debug_sata = {debug_link[31:8],debug_phy[7:0]} ; //
assign debug_sata = {debug_link[27:20],debug_phy[23:0]} ; // // assign debug_sata = {debug_link[27:20],debug_phy[23:0]} ; //
assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST); assign ll_h2d_last = (h2d_type_out == H2D_TYPE_FIS_LAST);
assign d2h_valid = d2h_nempty; assign d2h_valid = d2h_nempty;
......
...@@ -183,7 +183,8 @@ module ahci_top#( ...@@ -183,7 +183,8 @@ module ahci_top#(
output irq, // CPU interrupt request output irq, // CPU interrupt request
input [31:0] debug_in input [31:0] debug_in_phy,
input [31:0] debug_in_link
); );
...@@ -265,6 +266,11 @@ module ahci_top#( ...@@ -265,6 +266,11 @@ module ahci_top#(
wire dma_prd_irq_pend; // prd interrupt pending. This is just a condition for irq - actual will be generated after FIS OK wire dma_prd_irq_pend; // prd interrupt pending. This is just a condition for irq - actual will be generated after FIS OK
wire dma_cmd_busy; // output reg (DMA engine is processing PRDs) wire dma_cmd_busy; // output reg (DMA engine is processing PRDs)
wire dma_cmd_done; // output (last PRD is over) wire dma_cmd_done; // output (last PRD is over)
wire dma_abort_busy;
wire dma_abort_done;
wire axi_mismatch;
wire [31:0] dma_dout; // output[31:0] wire [31:0] dma_dout; // output[31:0]
wire dma_dav; // output wire dma_dav; // output
wire dma_re; // input wire dma_re; // input
...@@ -448,6 +454,8 @@ module ahci_top#( ...@@ -448,6 +454,8 @@ module ahci_top#(
wire pxci0; // pxCI current value wire pxci0; // pxCI current value
wire [9:0] last_jump_addr; wire [9:0] last_jump_addr;
wire [31:0] debug_dma;
wire [31:0] debug_dma1;
// Async FF // Async FF
always @ (posedge mrst or posedge mclk) begin always @ (posedge mrst or posedge mclk) begin
if (mrst) en_port <= 0; if (mrst) en_port <= 0;
...@@ -561,7 +569,7 @@ module ahci_top#( ...@@ -561,7 +569,7 @@ module ahci_top#(
.dma_cmd_busy (dma_cmd_busy), // input .dma_cmd_busy (dma_cmd_busy), // input
/// .dma_cmd_done (dma_cmd_done), // input /// .dma_cmd_done (dma_cmd_done), // input
.dma_cmd_abort (dma_cmd_abort_fsm), // output .dma_cmd_abort (dma_cmd_abort_fsm), // output
.dma_abort_done (dma_abort_done), // input
.fis_first_invalid (frcv_first_invalid),// input .fis_first_invalid (frcv_first_invalid),// input
.fis_first_flush (frcv_first_flush), // output .fis_first_flush (frcv_first_flush), // output
...@@ -592,7 +600,7 @@ module ahci_top#( ...@@ -592,7 +600,7 @@ module ahci_top#(
.update_pio (frcv_update_pio), // output .update_pio (frcv_update_pio), // output
.update_prdbc (frcv_update_prdbc), // output .update_prdbc (frcv_update_prdbc), // output
.clear_bsy_drq (frcv_clear_bsy_drq), // output .clear_bsy_drq (frcv_clear_bsy_drq), // output
.clear_bsy_set_drq(frcv_clear_bsy_set_drq), //output .clear_bsy_set_drq (frcv_clear_bsy_set_drq), //output
.set_bsy (frcv_set_bsy), // output .set_bsy (frcv_set_bsy), // output
.set_sts_7f (frcv_set_sts_7f), // output .set_sts_7f (frcv_set_sts_7f), // output
.set_sts_80 (frcv_set_sts_80), // output .set_sts_80 (frcv_set_sts_80), // output
...@@ -601,9 +609,7 @@ module ahci_top#( ...@@ -601,9 +609,7 @@ module ahci_top#(
.decr_dwcw (frcv_decr_dwcw), // output increment pXferCntr after transmit by data transmitted) .decr_dwcw (frcv_decr_dwcw), // output increment pXferCntr after transmit by data transmitted)
// .decr_DXC_dw (data_out_dwords), // output[11:2] **** Probably not needed // .decr_DXC_dw (data_out_dwords), // output[11:2] **** Probably not needed
.pxcmd_fre (pcmd_fre), // input .pxcmd_fre (pcmd_fre), // input
.pPioXfer (pPioXfer), // input .pPioXfer (pPioXfer), // input
.tfd_sts (tfd_sts), // input[7:0] .tfd_sts (tfd_sts), // input[7:0]
/// .tfd_err (tfd_err), // input[7:0] /// .tfd_err (tfd_err), // input[7:0]
.fis_i (fis_i), // input .fis_i (fis_i), // input
...@@ -698,7 +704,10 @@ module ahci_top#( ...@@ -698,7 +704,10 @@ module ahci_top#(
.afi_cache_set (set_axi_cache_mode), // output .afi_cache_set (set_axi_cache_mode), // output
.was_hba_rst (was_hba_rst), // output .was_hba_rst (was_hba_rst), // output
.was_port_rst (was_port_rst), // output .was_port_rst (was_port_rst), // output
.debug_in ({2'b0, last_jump_addr[9:0], debug_in[19:0]}) .debug_in0 (debug_dma), // input[31:0]
.debug_in1 (debug_dma1), // debug_in_link), // input[31:0]
.debug_in2 (debug_in_phy), // input[31:0] // debug from phy/link
.debug_in3 ({22'b0, last_jump_addr[9:0]}) // input[31:0]// Last jump address in the AHDCI sequencer
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
,.datascope_clk (datascope_clk), // input ,.datascope_clk (datascope_clk), // input
.datascope_waddr (datascope_waddr), // input[9:0] .datascope_waddr (datascope_waddr), // input[9:0]
...@@ -823,6 +832,9 @@ module ahci_top#( ...@@ -823,6 +832,9 @@ module ahci_top#(
.cmd_busy (dma_cmd_busy), // dma_cmd_busy), // output reg Some data to transmit! .cmd_busy (dma_cmd_busy), // dma_cmd_busy), // output reg Some data to transmit!
.cmd_done (dma_cmd_done), // output .cmd_done (dma_cmd_done), // output
.abort_busy (dma_abort_busy),
.abort_done (dma_abort_done),
.axi_mismatch (axi_mismatch), // handled, but may report as an error - axi counters are 0, but calculated ones are not
.sys_out (dma_dout), // output[31:0] .sys_out (dma_dout), // output[31:0]
.sys_dav (dma_dav), // output .sys_dav (dma_dav), // output
.sys_re (dma_re), // input .sys_re (dma_re), // input
...@@ -874,7 +886,9 @@ module ahci_top#( ...@@ -874,7 +886,9 @@ module ahci_top#(
.afi_rresp (afi_rresp), // input[1:0] .afi_rresp (afi_rresp), // input[1:0]
.afi_rcount (afi_rcount), // input[7:0] .afi_rcount (afi_rcount), // input[7:0]
.afi_racount (afi_racount), // input[2:0] .afi_racount (afi_racount), // input[2:0]
.afi_rdissuecap1en (afi_rdissuecap1en) // output .afi_rdissuecap1en (afi_rdissuecap1en), // output
.debug_out (debug_dma), // output[31:0]
.debug_out1 (debug_dma1) // output[31:0]
); );
ahci_fis_receive #( ahci_fis_receive #(
...@@ -1023,15 +1037,31 @@ wire [9:0] xmit_dbg_01; ...@@ -1023,15 +1037,31 @@ wire [9:0] xmit_dbg_01;
localparam DATASCOPE_CFIS_START=0; localparam DATASCOPE_CFIS_START=0;
reg [ADDRESS_BITS-1:0] datascope_waddr_r; reg [ADDRESS_BITS-1:0] datascope_waddr_r;
reg [1:0] datascope_run; reg [1:0] datascope_run;
reg [8:0] datascope_cntr; /// reg [8:0] datascope_cntr;
reg datascope_was_busy; /// reg datascope_was_busy;
assign datascope_clk = mclk; assign datascope_clk = mclk;
// assign datascope_di = datascope_run[0]? {h2d_type, dma_dav, datascope_was_busy, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
assign datascope_di = datascope_run[0]? {h2d_type, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || (datascope_run == 2);
assign datascope_waddr = datascope_waddr_r; assign datascope_waddr = datascope_waddr_r;
// assign datascope_di = datascope_run[0]? {h2d_type, dma_dav, datascope_was_busy, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
/// assign datascope_di = datascope_run[0]? {h2d_type, xmit_dbg_01, datascope_cntr[3:0], h2d_data[15:0]} : {{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
always @(posedge mclk) begin // Datascope provides just outgoing data, followed by the dword counter with 16'hffff in the high word
// assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || (datascope_run == 2);
// assign datascope_di = datascope_run[0]? {h2d_data[31:0]} : {16'hffff,{16-ADDRESS_BITS{1'b0}},datascope_waddr_r};
assign datascope_we = (datascope_run[0] && h2d_valid && h2d_ready) || (datascope_run == 2) || d2h_ready;
assign datascope_di = d2h_ready? {d2h_type, d2h_data[29:0]}:(datascope_run[0]? {h2d_data[31:0]} : {16'hffff,{16-ADDRESS_BITS{1'b0}},datascope_waddr_r});
/// assign datascope_we = |datascope_run;
/*
assign datascope_di = datascope_run[0]? {h2d_type, // 2 bits
dma_ct_re[0], // 1 bit
dma_ct_addr[4:0], // 5 bits
//------
dma_ct_data[7:0], //8 bits (lower)
datascope_cntr[3:0], // 4 bits
h2d_data[11:0]} : // 12 bits
{{32-ADDRESS_BITS{1'b0}},datascope_waddr_r};
*/ always @(posedge mclk) begin
if (mrst) datascope_run[0] <= 0; if (mrst) datascope_run[0] <= 0;
else if (fsnd_cfis_xmit) datascope_run[0] <= 1; else if (fsnd_cfis_xmit) datascope_run[0] <= 1;
else if (h2d_valid && h2d_ready && (h2d_type == 2)) datascope_run[0] <= 0; else if (h2d_valid && h2d_ready && (h2d_type == 2)) datascope_run[0] <= 0;
...@@ -1041,12 +1071,17 @@ wire [9:0] xmit_dbg_01; ...@@ -1041,12 +1071,17 @@ wire [9:0] xmit_dbg_01;
if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START; if (fsnd_cfis_xmit) datascope_waddr_r <= DATASCOPE_CFIS_START;
else if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1; else if (datascope_we) datascope_waddr_r <= datascope_waddr_r + 1;
if (fsnd_cfis_xmit) datascope_cntr <= 0; /// if (fsnd_cfis_xmit) datascope_cntr <= 0;
else datascope_cntr <= datascope_cntr + 1; /// else datascope_cntr <= datascope_cntr + 1;
if (fsnd_cfis_xmit) datascope_was_busy <= ahci_fis_transmit_busy; /// if (fsnd_cfis_xmit) datascope_was_busy <= ahci_fis_transmit_busy;
end end
/*
.ct_addr (dma_ct_addr), // output[4:0] reg
.ct_re (dma_ct_re), // output[1:0]
.ct_data (dma_ct_data), // input[31:0]
*/
`endif `endif
......
...@@ -115,7 +115,10 @@ module axi_ahci_regs#( ...@@ -115,7 +115,10 @@ module axi_ahci_regs#(
output afi_cache_set, output afi_cache_set,
output was_hba_rst, // last reset was hba reset (not counting system reset) output was_hba_rst, // last reset was hba reset (not counting system reset)
output was_port_rst, // last reset was port reset output was_port_rst, // last reset was port reset
input [31:0] debug_in input [31:0] debug_in0,
input [31:0] debug_in1,
input [31:0] debug_in2,
input [31:0] debug_in3
`ifdef USE_DATASCOPE `ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read) // Datascope interface (write to memory that can be software-read)
,input datascope_clk, ,input datascope_clk,
...@@ -188,6 +191,7 @@ module axi_ahci_regs#( ...@@ -188,6 +191,7 @@ module axi_ahci_regs#(
reg wait_first_access = RESET_TO_FIRST_ACCESS; // keep port reset until first access reg wait_first_access = RESET_TO_FIRST_ACCESS; // keep port reset until first access
wire any_access = bram_wen_r || bram_ren[0]; wire any_access = bram_wen_r || bram_ren[0];
reg debug_rd_r; reg debug_rd_r;
reg [31:0] debug_r;
assign bram_addr = bram_ren[0] ? bram_raddr[ADDRESS_BITS-1:0] : (bram_wen_r ? bram_waddr_r : bram_waddr[ADDRESS_BITS-1:0]); assign bram_addr = bram_ren[0] ? bram_raddr[ADDRESS_BITS-1:0] : (bram_wen_r ? bram_waddr_r : bram_waddr[ADDRESS_BITS-1:0]);
...@@ -198,7 +202,6 @@ module axi_ahci_regs#( ...@@ -198,7 +202,6 @@ module axi_ahci_regs#(
assign was_hba_rst = was_hba_rst_r[0]; assign was_hba_rst = was_hba_rst_r[0];
assign was_port_rst = was_port_rst_r[0]; assign was_port_rst = was_port_rst_r[0];
always @(posedge aclk) begin always @(posedge aclk) begin
if (arst) write_busy_r <= 0; if (arst) write_busy_r <= 0;
...@@ -207,7 +210,7 @@ module axi_ahci_regs#( ...@@ -207,7 +210,7 @@ module axi_ahci_regs#(
if (bram_wen) bram_wdata_r <= bram_wdata; if (bram_wen) bram_wdata_r <= bram_wdata;
if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_in : bram_rdata; // if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_in : bram_rdata;
bram_wstb_r <= {4{bram_wen}} & bram_wstb; bram_wstb_r <= {4{bram_wen}} & bram_wstb;
...@@ -215,8 +218,17 @@ module axi_ahci_regs#( ...@@ -215,8 +218,17 @@ module axi_ahci_regs#(
if (bram_wen) bram_waddr_r <= bram_waddr[ADDRESS_BITS-1:0]; if (bram_wen) bram_waddr_r <= bram_waddr[ADDRESS_BITS-1:0];
if (bram_ren[0]) debug_rd_r <= &bram_raddr[ADDRESS_BITS-1:4]; // last 16 DWORDs (With AXIBRAM_BITS will be duplicated)
if (bram_ren[0]) debug_r <= bram_raddr[1]? (bram_raddr[0] ? debug_in3: debug_in2):
(bram_raddr[0] ? debug_in1: debug_in0);
if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_r : bram_rdata;
end end
//debug_rd_r
generate generate
genvar i; genvar i;
for (i=0; i < 32; i=i+1) begin: bit_type_block for (i=0; i < 32; i=i+1) begin: bit_type_block
...@@ -281,10 +293,6 @@ module axi_ahci_regs#( ...@@ -281,10 +293,6 @@ module axi_ahci_regs#(
if (pgm_fsm_set_w) pgm_ad <= ahci_regs_di[17:0]; if (pgm_fsm_set_w) pgm_ad <= ahci_regs_di[17:0];
end end
always @(posedge aclk) begin
if (bram_ren[0]) debug_rd_r <= &bram_raddr[ADDRESS_BITS-1:4]; // last 16 DWORDs (With AXIBRAM_BITS will be duplicated)
end
//debug_rd_r
/* /*
......
/*******************************************************************************
* Module: axi_hp_abort
* Date:2016-02-07
* Author: andrey
* Description: Trying to gracefully reset AXI HP after aborted transmission
* For read channel - just keep afi_rready on until RD FIFO is empty (afi_rcount ==0)
* For write - keep track aof all what was sent so far, assuming aw is always ahead of w
* Reset only by global reset (system POR) - probably it is not possible to just
* reset PL or relaod bitfile,
*
* Copyright (c) 2016 Elphel, Inc .
* axi_hp_abort.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* axi_hp_abort.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module axi_hp_abort(
input hclk,
input hrst, // just disables processing inputs
input abort,
output busy, // should disable control of afi_wvalid, afi_awid
output reg done,
input afi_awvalid, // afi_awready is supposed to be always on when afi_awvalid (caller uses fifo counetrs) ?
input afi_awready, //
input [ 5:0] afi_awid,
input [3:0] afi_awlen,
input afi_wvalid_in,
input afi_wready,
output afi_wvalid,
output reg [ 5:0] afi_wid,
input afi_arvalid,
input afi_arready,
input [ 3:0] afi_arlen,
input afi_rready_in,
input afi_rvalid,
output afi_rready,
output afi_wlast,
// TODO: Try to resolve problems when afi_racount, afi_wacount afi_wcount do not match expected
input [ 2:0] afi_racount,
input [ 7:0] afi_rcount,
input [ 5:0] afi_wacount,
input [ 7:0] afi_wcount,
output reg dirty, // single bit to be sampled in different clock domain to see if flushing is needed
output reg axi_mismatch, // calculated as 'dirty' but axi hp counters are 0
output [21:0] debug
);
reg busy_r;
wire done_w = busy_r && !dirty ;
reg [3:0] aw_lengths_ram[0:31];
reg [4:0] aw_lengths_waddr = 0;
reg [4:0] aw_lengths_raddr = 0;
reg [5:0] aw_count = 0;
reg [7:0] w_count = 0;
reg [7:0] r_count = 0;
reg adav = 0;
wire arwr = !hrst && afi_arvalid && afi_arready;
wire drd = !hrst && afi_rvalid && afi_rready_in;
wire awr = !hrst && afi_awvalid && afi_awready;
reg ard_r = 0; // additional length read if not much data
wire ard = adav && ((|w_count[7:4]) || ard_r);
wire wwr = !hrst && afi_wready && afi_wvalid_in;
reg afi_rready_r;
reg afi_wlast_r; // wait one cycle after last in each burst (just to ease timing)
reg busy_aborting; // actually aborting
wire reset_counters = busy_r && !busy_aborting;
assign busy = busy_r;
assign afi_rready = busy_aborting && (|r_count) && ((|afi_rcount[7:1]) || (!afi_rready_r && afi_rcount[0]));
assign afi_wlast = busy_aborting && adav && (w_count[3:0] == aw_lengths_ram[aw_lengths_raddr]);
assign afi_wvalid = busy_aborting && adav && !afi_wlast_r;
assign debug = {aw_count[5:0], w_count[7:0], r_count[7:0]};
// Watch for transactios performed by others (and this one too)
always @ (posedge hclk) begin
// read channel
if (reset_counters) r_count <= 0;
else if (drd)
if (arwr) r_count <= r_count + {4'b0, afi_arlen};
else r_count <= r_count - 1;
else
if (arwr) r_count <= w_count + {4'b0, afi_arlen} + 1;
// write channel
if (awr) afi_wid <= afi_awid; // one command is supposed to use just one awid/wid
if (awr) aw_lengths_ram [aw_lengths_waddr] <= afi_awlen;
if (reset_counters) aw_lengths_waddr <= 0;
else if (awr) aw_lengths_waddr <= aw_lengths_waddr + 1;
if (reset_counters) aw_lengths_raddr <= 0;
else if (ard) aw_lengths_raddr <= aw_lengths_raddr + 1;
if (reset_counters) aw_count <= 0;
else if ( awr && !ard) aw_count <= aw_count + 1;
else if (!awr && ard) aw_count <= aw_count - 1;
adav <= !reset_counters && (|aw_count[5:1]) || ((awr || aw_count[0]) && !ard) || (awr && aw_count[0]);
ard_r <= !ard && adav && (w_count[3:0] > aw_lengths_ram[aw_lengths_raddr]);
if (reset_counters) w_count <= 0;
else if (wwr)
if (ard) w_count <= w_count - {4'b0, aw_lengths_ram[aw_lengths_raddr]};
else w_count <= w_count + 1;
else
if (ard) w_count <= w_count - {4'b0, aw_lengths_ram[aw_lengths_raddr]} - 1;
dirty <= (|r_count) || (|aw_count); // assuming w_count can never be non-zero? - no
end
// flushing part
always @ (posedge hclk) begin
if (abort) busy_r <= 1;
else if (done_w) busy_r <= 0;
if (abort && ((|afi_racount) || (|afi_rcount) || (|afi_wacount) || (|afi_wcount))) busy_aborting <= 1;
else if (done_w) busy_aborting <= 0;
done <= done_w;
afi_rready_r <= afi_rready;
afi_wlast_r <= afi_wlast;
axi_mismatch <= busy && !busy_aborting && dirty; //
end
endmodule
...@@ -224,7 +224,8 @@ ...@@ -224,7 +224,8 @@
reg [2:0] nhrst_r; reg [2:0] nhrst_r;
wire hrst = !nhrst_r[2]; wire hrst = !nhrst_r[2];
wire [31:0] debug_sata; wire [31:0] debug_phy;
wire [31:0] debug_link;
always @ (posedge hclk or posedge arst) begin always @ (posedge hclk or posedge arst) begin
if (arst) nhrst_r <= 0; if (arst) nhrst_r <= 0;
...@@ -365,7 +366,8 @@ ...@@ -365,7 +366,8 @@
.sctl_ipm (sctl_ipm), // output[3:0] .sctl_ipm (sctl_ipm), // output[3:0]
.sctl_spd (sctl_spd), // output[3:0] .sctl_spd (sctl_spd), // output[3:0]
.irq (irq), // output .irq (irq), // output
.debug_in (debug_sata) // input[31:0] .debug_in_phy (debug_phy), // input[31:0]
.debug_in_link (debug_link) // input[31:0]
); );
ahci_sata_layers #( ahci_sata_layers #(
...@@ -424,7 +426,8 @@ ...@@ -424,7 +426,8 @@
.txn_out (TXN), // output wire .txn_out (TXN), // output wire
.rxp_in (RXP), // input wire .rxp_in (RXP), // input wire
.rxn_in (RXN), // input wire .rxn_in (RXN), // input wire
.debug_sata (debug_sata) // output[31:0] .debug_phy (debug_phy), // output[31:0]
.debug_link (debug_link) // output[31:0]
); );
......
/******************************************************************************* /*******************************************************************************
* Module: action_decoder * Module: action_decoder
* Date:2016-01-27 * Date:2016-02-07
* Author: auto-generated file, see ahci_fsm_sequence.py * Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Decode sequencer code to 1-hot actions * Description: Decode sequencer code to 1-hot actions
*******************************************************************************/ *******************************************************************************/
......
/******************************************************************************* /*******************************************************************************
* Module: condition_mux * Module: condition_mux
* Date:2016-01-27 * Date:2016-02-07
* Author: auto-generated file, see ahci_fsm_sequence.py * Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Select condition * Description: Select condition
*******************************************************************************/ *******************************************************************************/
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
module condition_mux ( module condition_mux (
input clk, input clk,
input ce, // enable recording all conditions
input [ 7:0] sel, input [ 7:0] sel,
output condition, output condition,
input ST_NB_ND, input ST_NB_ND,
...@@ -57,57 +58,104 @@ module condition_mux ( ...@@ -57,57 +58,104 @@ module condition_mux (
input X_RDY_COLLISION); input X_RDY_COLLISION);
wire [44:0] masked; wire [44:0] masked;
reg [43:0] registered;
reg [ 5:0] cond_r; reg [ 5:0] cond_r;
assign condition = |cond_r; assign condition = |cond_r;
assign masked[ 0] = ST_NB_ND && sel[ 2] && sel[ 1] && sel[ 0]; assign masked[ 0] = registered[ 0] && sel[ 2] && sel[ 1] && sel[ 0];
assign masked[ 1] = PXCI0_NOT_CMDTOISSUE && sel[ 3] && sel[ 1] && sel[ 0]; assign masked[ 1] = registered[ 1] && sel[ 3] && sel[ 1] && sel[ 0];
assign masked[ 2] = PCTI_CTBAR_XCZ && sel[ 4] && sel[ 1] && sel[ 0]; assign masked[ 2] = registered[ 2] && sel[ 4] && sel[ 1] && sel[ 0];
assign masked[ 3] = PCTI_XCZ && sel[ 5] && sel[ 1] && sel[ 0]; assign masked[ 3] = registered[ 3] && sel[ 5] && sel[ 1] && sel[ 0];
assign masked[ 4] = NST_D2HR && sel[ 6] && sel[ 1] && sel[ 0]; assign masked[ 4] = registered[ 4] && sel[ 6] && sel[ 1] && sel[ 0];
assign masked[ 5] = NPD_NCA && sel[ 7] && sel[ 1] && sel[ 0]; assign masked[ 5] = registered[ 5] && sel[ 7] && sel[ 1] && sel[ 0];
assign masked[ 6] = CHW_DMAA && sel[ 3] && sel[ 2] && sel[ 0]; assign masked[ 6] = registered[ 6] && sel[ 3] && sel[ 2] && sel[ 0];
assign masked[ 7] = SCTL_DET_CHANGED_TO_4 && sel[ 4] && sel[ 2] && sel[ 0]; assign masked[ 7] = registered[ 7] && sel[ 4] && sel[ 2] && sel[ 0];
assign masked[ 8] = SCTL_DET_CHANGED_TO_1 && sel[ 5] && sel[ 2] && sel[ 0]; assign masked[ 8] = registered[ 8] && sel[ 5] && sel[ 2] && sel[ 0];
assign masked[ 9] = PXSSTS_DET_NE_3 && sel[ 6] && sel[ 2] && sel[ 0]; assign masked[ 9] = registered[ 9] && sel[ 6] && sel[ 2] && sel[ 0];
assign masked[10] = PXSSTS_DET_EQ_1 && sel[ 7] && sel[ 2] && sel[ 0]; assign masked[10] = registered[10] && sel[ 7] && sel[ 2] && sel[ 0];
assign masked[11] = NPCMD_FRE && sel[ 4] && sel[ 3] && sel[ 0]; assign masked[11] = registered[11] && sel[ 4] && sel[ 3] && sel[ 0];
assign masked[12] = FIS_OK && sel[ 5] && sel[ 3] && sel[ 0]; assign masked[12] = registered[12] && sel[ 5] && sel[ 3] && sel[ 0];
assign masked[13] = FIS_ERR && sel[ 6] && sel[ 3] && sel[ 0]; assign masked[13] = registered[13] && sel[ 6] && sel[ 3] && sel[ 0];
assign masked[14] = FIS_FERR && sel[ 7] && sel[ 3] && sel[ 0]; assign masked[14] = registered[14] && sel[ 7] && sel[ 3] && sel[ 0];
assign masked[15] = FIS_EXTRA && sel[ 5] && sel[ 4] && sel[ 0]; assign masked[15] = registered[15] && sel[ 5] && sel[ 4] && sel[ 0];
assign masked[16] = FIS_FIRST_INVALID && sel[ 6] && sel[ 4] && sel[ 0]; assign masked[16] = registered[16] && sel[ 6] && sel[ 4] && sel[ 0];
assign masked[17] = FR_D2HR && sel[ 7] && sel[ 4] && sel[ 0]; assign masked[17] = registered[17] && sel[ 7] && sel[ 4] && sel[ 0];
assign masked[18] = FIS_DATA && sel[ 6] && sel[ 5] && sel[ 0]; assign masked[18] = registered[18] && sel[ 6] && sel[ 5] && sel[ 0];
assign masked[19] = FIS_ANY && sel[ 7] && sel[ 5] && sel[ 0]; assign masked[19] = registered[19] && sel[ 7] && sel[ 5] && sel[ 0];
assign masked[20] = NB_ND_D2HR_PIO && sel[ 7] && sel[ 6] && sel[ 0]; assign masked[20] = registered[20] && sel[ 7] && sel[ 6] && sel[ 0];
assign masked[21] = D2HR && sel[ 3] && sel[ 2] && sel[ 1]; assign masked[21] = registered[21] && sel[ 3] && sel[ 2] && sel[ 1];
assign masked[22] = SDB && sel[ 4] && sel[ 2] && sel[ 1]; assign masked[22] = registered[22] && sel[ 4] && sel[ 2] && sel[ 1];
assign masked[23] = DMA_ACT && sel[ 5] && sel[ 2] && sel[ 1]; assign masked[23] = registered[23] && sel[ 5] && sel[ 2] && sel[ 1];
assign masked[24] = DMA_SETUP && sel[ 6] && sel[ 2] && sel[ 1]; assign masked[24] = registered[24] && sel[ 6] && sel[ 2] && sel[ 1];
assign masked[25] = BIST_ACT_FE && sel[ 7] && sel[ 2] && sel[ 1]; assign masked[25] = registered[25] && sel[ 7] && sel[ 2] && sel[ 1];
assign masked[26] = BIST_ACT && sel[ 4] && sel[ 3] && sel[ 1]; assign masked[26] = registered[26] && sel[ 4] && sel[ 3] && sel[ 1];
assign masked[27] = PIO_SETUP && sel[ 5] && sel[ 3] && sel[ 1]; assign masked[27] = registered[27] && sel[ 5] && sel[ 3] && sel[ 1];
assign masked[28] = NB_ND && sel[ 6] && sel[ 3] && sel[ 1]; assign masked[28] = registered[28] && sel[ 6] && sel[ 3] && sel[ 1];
assign masked[29] = TFD_STS_ERR && sel[ 7] && sel[ 3] && sel[ 1]; assign masked[29] = registered[29] && sel[ 7] && sel[ 3] && sel[ 1];
assign masked[30] = FIS_I && sel[ 5] && sel[ 4] && sel[ 1]; assign masked[30] = registered[30] && sel[ 5] && sel[ 4] && sel[ 1];
assign masked[31] = PIO_I && sel[ 6] && sel[ 4] && sel[ 1]; assign masked[31] = registered[31] && sel[ 6] && sel[ 4] && sel[ 1];
assign masked[32] = NPD && sel[ 7] && sel[ 4] && sel[ 1]; assign masked[32] = registered[32] && sel[ 7] && sel[ 4] && sel[ 1];
assign masked[33] = PIOX && sel[ 6] && sel[ 5] && sel[ 1]; assign masked[33] = registered[33] && sel[ 6] && sel[ 5] && sel[ 1];
assign masked[34] = XFER0 && sel[ 7] && sel[ 5] && sel[ 1]; assign masked[34] = registered[34] && sel[ 7] && sel[ 5] && sel[ 1];
assign masked[35] = PIOX_XFER0 && sel[ 7] && sel[ 6] && sel[ 1]; assign masked[35] = registered[35] && sel[ 7] && sel[ 6] && sel[ 1];
assign masked[36] = CTBAA_CTBAP && sel[ 4] && sel[ 3] && sel[ 2]; assign masked[36] = registered[36] && sel[ 4] && sel[ 3] && sel[ 2];
assign masked[37] = CTBAP && sel[ 5] && sel[ 3] && sel[ 2]; assign masked[37] = registered[37] && sel[ 5] && sel[ 3] && sel[ 2];
assign masked[38] = CTBA_B && sel[ 6] && sel[ 3] && sel[ 2]; assign masked[38] = registered[38] && sel[ 6] && sel[ 3] && sel[ 2];
assign masked[39] = CTBA_C && sel[ 7] && sel[ 3] && sel[ 2]; assign masked[39] = registered[39] && sel[ 7] && sel[ 3] && sel[ 2];
assign masked[40] = TX_ERR && sel[ 5] && sel[ 4] && sel[ 2]; assign masked[40] = registered[40] && sel[ 5] && sel[ 4] && sel[ 2];
assign masked[41] = SYNCESC_ERR && sel[ 6] && sel[ 4] && sel[ 2]; assign masked[41] = registered[41] && sel[ 6] && sel[ 4] && sel[ 2];
assign masked[42] = DMA_PRD_IRQ_PEND && sel[ 7] && sel[ 4] && sel[ 2]; assign masked[42] = registered[42] && sel[ 7] && sel[ 4] && sel[ 2];
assign masked[43] = X_RDY_COLLISION && sel[ 6] && sel[ 5] && sel[ 2]; assign masked[43] = registered[43] && sel[ 6] && sel[ 5] && sel[ 2];
assign masked[44] = !(|sel); // always TRUE condition (sel ==0) assign masked[44] = !(|sel); // always TRUE condition (sel ==0)
always @(posedge clk) begin always @(posedge clk) begin
if (ce) begin
registered[ 0] <= ST_NB_ND;
registered[ 1] <= PXCI0_NOT_CMDTOISSUE;
registered[ 2] <= PCTI_CTBAR_XCZ;
registered[ 3] <= PCTI_XCZ;
registered[ 4] <= NST_D2HR;
registered[ 5] <= NPD_NCA;
registered[ 6] <= CHW_DMAA;
registered[ 7] <= SCTL_DET_CHANGED_TO_4;
registered[ 8] <= SCTL_DET_CHANGED_TO_1;
registered[ 9] <= PXSSTS_DET_NE_3;
registered[10] <= PXSSTS_DET_EQ_1;
registered[11] <= NPCMD_FRE;
registered[12] <= FIS_OK;
registered[13] <= FIS_ERR;
registered[14] <= FIS_FERR;
registered[15] <= FIS_EXTRA;
registered[16] <= FIS_FIRST_INVALID;
registered[17] <= FR_D2HR;
registered[18] <= FIS_DATA;
registered[19] <= FIS_ANY;
registered[20] <= NB_ND_D2HR_PIO;
registered[21] <= D2HR;
registered[22] <= SDB;
registered[23] <= DMA_ACT;
registered[24] <= DMA_SETUP;
registered[25] <= BIST_ACT_FE;
registered[26] <= BIST_ACT;
registered[27] <= PIO_SETUP;
registered[28] <= NB_ND;
registered[29] <= TFD_STS_ERR;
registered[30] <= FIS_I;
registered[31] <= PIO_I;
registered[32] <= NPD;
registered[33] <= PIOX;
registered[34] <= XFER0;
registered[35] <= PIOX_XFER0;
registered[36] <= CTBAA_CTBAP;
registered[37] <= CTBAP;
registered[38] <= CTBA_B;
registered[39] <= CTBA_C;
registered[40] <= TX_ERR;
registered[41] <= SYNCESC_ERR;
registered[42] <= DMA_PRD_IRQ_PEND;
registered[43] <= X_RDY_COLLISION;
end
cond_r[ 0] <= |masked[ 7: 0]; cond_r[ 0] <= |masked[ 7: 0];
cond_r[ 1] <= |masked[15: 8]; cond_r[ 1] <= |masked[15: 8];
cond_r[ 2] <= |masked[23:16]; cond_r[ 2] <= |masked[23:16];
......
...@@ -53,7 +53,7 @@ actions = ['NOP', ...@@ -53,7 +53,7 @@ actions = ['NOP',
# FIS_TRANSMIT # FIS_TRANSMIT
'CLEAR_CMD_TO_ISSUE', 'CLEAR_CMD_TO_ISSUE',
# DMA # DMA
'DMA_ABORT', 'DMA_PRD_IRQ_CLEAR', 'DMA_ABORT*', 'DMA_PRD_IRQ_CLEAR',
# SATA TRANSPORT/LINK/PHY # SATA TRANSPORT/LINK/PHY
'XMIT_COMRESET', 'SEND_SYNC_ESC*', 'SET_OFFLINE', 'R_OK', 'R_ERR', 'XMIT_COMRESET', 'SEND_SYNC_ESC*', 'SET_OFFLINE', 'R_OK', 'R_ERR',
# FIS TRANSMIT/WAIT DONE # FIS TRANSMIT/WAIT DONE
...@@ -158,7 +158,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP}, ...@@ -158,7 +158,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{ GOTO:'P:NotRunning'}, { GOTO:'P:NotRunning'},
{LBL:'P:StartBitCleared', ACT: 'PXCI0_CLEAR'}, # pxci0_clear {LBL:'P:StartBitCleared', ACT: 'PXCI0_CLEAR'}, # pxci0_clear
{ ACT: 'DMA_ABORT'}, # dma_cmd_abort (should eventually clear PxCMD.CR)? { ACT: 'DMA_ABORT*'}, # dma_cmd_abort (should eventually clear PxCMD.CR)?
{ ACT: 'PCMD_CR_CLEAR'}, # pcmd_cr_reset { ACT: 'PCMD_CR_CLEAR'}, # pcmd_cr_reset
{ ACT: 'XFER_CNTR_CLEAR'}, # clear_xfer_cntr { ACT: 'XFER_CNTR_CLEAR'}, # clear_xfer_cntr
...@@ -477,6 +477,7 @@ def condition_mux_verilog(conditions, condition_vals, module_name, fanout, file= ...@@ -477,6 +477,7 @@ def condition_mux_verilog(conditions, condition_vals, module_name, fanout, file=
module %s ( module %s (
input clk, input clk,
input ce, // enable recording all conditions
input [%2d:0] sel, input [%2d:0] sel,
output condition,""" output condition,"""
v=max(condition_vals.values()) v=max(condition_vals.values())
...@@ -485,15 +486,14 @@ module %s ( ...@@ -485,15 +486,14 @@ module %s (
num_inputs += 1 num_inputs += 1
v >>= 1 v >>= 1
maximal_length = max([len(n) for n in conditions]) maximal_length = max([len(n) for n in conditions])
# numregs = (len(conditions) + fanout - 1) // fanout
numregs = (len(conditions) + fanout) // fanout # one more bit for 'always' (sel == 0) numregs = (len(conditions) + fanout) // fanout # one more bit for 'always' (sel == 0)
header = header_template%(module_name, datetime.date.today().isoformat(), os.path.basename(__file__), module_name, num_inputs-1) header = header_template%(module_name, datetime.date.today().isoformat(), os.path.basename(__file__), module_name, num_inputs-1)
print(header,file=file) print(header,file=file)
for input_name in conditions[:len(conditions)-1]: for input_name in conditions[:len(conditions)-1]:
print(" input %s,"%(input_name),file=file) print(" input %s,"%(input_name), file=file)
print(" input %s);\n"%(conditions[-1]),file=file) print(" input %s);\n"%(conditions[-1]), file=file)
# print(" wire [%2d:0] masked;"%(len(conditions)-1),file=file) print(" wire [%2d:0] masked;"%(len(conditions)), file=file)
print(" wire [%2d:0] masked;"%(len(conditions)),file=file) print(" reg [%2d:0] registered;"%(len(conditions) -1),file=file)
if numregs > 1: if numregs > 1:
print(" reg [%2d:0] cond_r;\n"%(numregs-1),file=file) print(" reg [%2d:0] cond_r;\n"%(numregs-1),file=file)
else: else:
...@@ -505,7 +505,8 @@ module %s ( ...@@ -505,7 +505,8 @@ module %s (
print(" assign condition = cond_r;\n",file=file) print(" assign condition = cond_r;\n",file=file)
for b in range (len(conditions)): for b in range (len(conditions)):
print(" assign masked[%2d] = %s %s"%(b, conditions[b] , " "*(maximal_length - len(conditions[b]))),end="",file=file) # print(" assign masked[%2d] = %s %s"%(b, conditions[b] , " "*(maximal_length - len(conditions[b]))),end="",file=file)
print(" assign masked[%2d] = registered[%2d] "%(b, b),end="",file=file)
d = condition_vals[conditions[b]] d = condition_vals[conditions[b]]
for nb in range(num_inputs-1,-1,-1): for nb in range(num_inputs-1,-1,-1):
...@@ -515,6 +516,12 @@ module %s ( ...@@ -515,6 +516,12 @@ module %s (
print(" assign masked[%2d] = !(|sel); // always TRUE condition (sel ==0)"%(len(conditions)), file=file) print(" assign masked[%2d] = !(|sel); // always TRUE condition (sel ==0)"%(len(conditions)), file=file)
print ("\n always @(posedge clk) begin", file=file) print ("\n always @(posedge clk) begin", file=file)
print (" if (ce) begin", file=file)
for b in range (len(conditions)):
print(" registered[%2d] <= %s;"%(b, conditions[b]),file=file)
print (" end", file=file)
for nb in range (numregs): for nb in range (numregs):
ll = nb * fanout ll = nb * fanout
# hl = min(ll + fanout, len(conditions)) -1 # hl = min(ll + fanout, len(conditions)) -1
......
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
, .INIT_0E (256'h00F60082011000ED24FB250200C000390401011000E624FB2502018000500101) , .INIT_0E (256'h00F60082011000ED24FB250200C000390401011000E624FB2502018000500101)
, .INIT_0F (256'h0100020101000021021001000021004400F6000000F6011000F424FB250200C0) , .INIT_0F (256'h0100020101000021021001000021004400F6000000F6011000F424FB250200C0)
, .INIT_10 (256'h0000000000000000000000000000000000000000000000390041000001000000) , .INIT_10 (256'h0000000000000000000000000000000000000000000000390041000001000000)
, .INITP_00 (256'hC8220098170902401E272722222800309418800820809C802018880022222222) , .INITP_00 (256'hC8220098170902401E272722222800309418810820809C802018880022222222)
, .INITP_01 (256'h22082227209C82720A09C22089C680272181A01CB889C8605A2A89C882068270) , .INITP_01 (256'h22082227209C82720A09C22089C680272181A01CB889C8605A2A89C882068270)
, .INITP_02 (256'h0000000000000000000000000000000000000000000000000000000000000082) , .INITP_02 (256'h0000000000000000000000000000000000000000000000000000000000000082)
This diff is collapsed.
...@@ -763,14 +763,34 @@ localparam COMMAND_TABLE = 32'h3f00; // 256 bytes for a command table in the sys ...@@ -763,14 +763,34 @@ localparam COMMAND_TABLE = 32'h3f00; // 256 bytes for a command table in the sys
localparam IDENTIFY_BUF = 32'h3d00; // 512 bytes for a command table in the system memory localparam IDENTIFY_BUF = 32'h3d00; // 512 bytes for a command table in the system memory
localparam PRD_OFFSET = 'h80; // start of PRD table - 128-th byte in command table localparam PRD_OFFSET = 'h80; // start of PRD table - 128-th byte in command table
localparam ATA_IDFY = 'hec; // Identify command localparam ATA_IDFY = 'hec; // Identify command
localparam ATA_WDMA = 'hca; // Identify command localparam ATA_WDMA = 'hca; // Write to device in DMA mode
localparam ATA_WBUF_PIO = 'he8; // Write 512 bytes to device buffer in PIO mode @SuppressThisWarning VEditor - not yet used
localparam ATA_WBUF_DMA = 'heb; // Write 512 bytes to device buffer in DMA mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RDMA = 'hc8; // Read from device in DMA mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RBUF_PIO = 'he4; // Read 512 bytes from device buffer in PIO mode @SuppressThisWarning VEditor - not yet used
localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mode @SuppressThisWarning VEditor - not yet used
reg [31:0] sysmem[0:4095]; reg [31:0] sysmem[0:4095];
// connect system memory ty AXI_NP RD and WR channels // connect system memory ty AXI_NP RD and WR channels
// assign HCLK = dut.ps7_i.SAXIHP3ACLK; // shortcut name // assign HCLK = dut.ps7_i.SAXIHP3ACLK; // shortcut name
// afi loopback // afi loopback
assign #1 afi_sim_rd_valid = afi_sim_rd_ready; // This is for no-delay memory
// assign #1 afi_sim_rd_valid = afi_sim_rd_ready;
// Make long delay for the first memory read, zero - for the next
reg afi_sim_rd_ready_r;
integer read_system_delay;
localparam SYSTEM_MEMORY_READ_LATENCY = 10; // HCLK cycles
always @ (posedge HCLK) begin
if (!afi_sim_rd_ready) read_system_delay <= SYSTEM_MEMORY_READ_LATENCY;
else if (read_system_delay != 0) read_system_delay <= read_system_delay - 1;
afi_sim_rd_ready_r <= afi_sim_rd_ready && (read_system_delay == 0);
end
assign #1 afi_sim_rd_valid = afi_sim_rd_ready && afi_sim_rd_ready_r;
assign #1 afi_sim_rd_resp = afi_sim_rd_ready?2'b0:2'bx; assign #1 afi_sim_rd_resp = afi_sim_rd_ready?2'b0:2'bx;
assign #1 afi_sim_wr_ready = 1; // afi_sim_wr_valid; assign #1 afi_sim_wr_ready = 1; // afi_sim_wr_valid;
assign #1 afi_sim_bresp_latency=4'h5; assign #1 afi_sim_bresp_latency=4'h5;
...@@ -809,7 +829,9 @@ localparam ATA_WDMA = 'hca; // Identify command ...@@ -809,7 +829,9 @@ localparam ATA_WDMA = 'hca; // Identify command
task setup_pio_read_identify_command_simple; task setup_pio_read_identify_command_simple;
input integer data_len;
input integer prd_int; // [0] - first prd interrupt, ... [31] - 31-st input integer prd_int; // [0] - first prd interrupt, ... [31] - 31-st
integer i; integer i;
begin begin
// clear system memory for command // clear system memory for command
...@@ -822,7 +844,7 @@ localparam ATA_WDMA = 'hca; // Identify command ...@@ -822,7 +844,7 @@ localparam ATA_WDMA = 'hca; // Identify command
// All other 4 DWORDs are 0 for this command // All other 4 DWORDs are 0 for this command
// Set PRDT (single item) TODO: later check multiple small ones // Set PRDT (single item) TODO: later check multiple small ones
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF; sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 0] = SYS_MEM_START + IDENTIFY_BUF;
sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 3] = (prd_int[0] << 31) | 511; // 512 bytes in this PRDT sysmem[((COMMAND_TABLE + PRD_OFFSET) >> 2) + 3] = (prd_int[0] << 31) | (data_len-1); // 512 bytes in this PRDT
// Setup command header // Setup command header
maxigp1_writep ((CLB_OFFS32 + 0) << 2, (5 << 0) | // 'CFL' - number of DWORDs in thes CFIS maxigp1_writep ((CLB_OFFS32 + 0) << 2, (5 << 0) | // 'CFL' - number of DWORDs in thes CFIS
(0 << 5) | // 'A' Not ATAPI (0 << 5) | // 'A' Not ATAPI
...@@ -939,7 +961,7 @@ localparam ATA_WDMA = 'hca; // Identify command ...@@ -939,7 +961,7 @@ localparam ATA_WDMA = 'hca; // Identify command
// fill ATA command // fill ATA command
sysmem[(COMMAND_TABLE >> 2) + 0] = FIS_H2DR | // FIS type - H2D register (0x27) sysmem[(COMMAND_TABLE >> 2) + 0] = FIS_H2DR | // FIS type - H2D register (0x27)
('h80 << 8) | // set C = 1 ('h80 << 8) | // set C = 1
(ATA_WDMA << 16) | // Command = 0xEC (IDFY) (ATA_WDMA << 16) | // Command = 0xCA
( 0 << 24); // features = 0 ? ( 0 << 24); // features = 0 ?
sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command) sysmem[(COMMAND_TABLE >> 2) + 1] = lba & 'hffffff; // 24 LSBs of LBA (48-bit require different ATA command)
sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256) sysmem[(COMMAND_TABLE >> 2) + 3] = 1; // 1 logical sector (0 means 256)
...@@ -1053,11 +1075,12 @@ initial begin //Host ...@@ -1053,11 +1075,12 @@ initial begin //Host
maxigp1_print (HBA_PORT__PxSSTS__DET__ADDR << 2,"HBA_PORT__PxSSTS__DET__ADDR"); maxigp1_print (HBA_PORT__PxSSTS__DET__ADDR << 2,"HBA_PORT__PxSSTS__DET__ADDR");
// setup_pio_read_identify_command_simple(1); // prdt interrupt for entry 0 // setup_pio_read_identify_command_simple(512,1); // prdt interrupt for entry 0
// setup_pio_read_identify_command_shifted(1); // prdt interrupt for entry 0 setup_pio_read_identify_command_simple(2560,1); // intentionally too long
/// setup_pio_read_identify_command_shifted(1); // prdt interrupt for entry 0
/// setup_pio_read_identify_command_multi4(1,27,71,83); // prdt interrupt for entry 0 /// setup_pio_read_identify_command_multi4(1,27,71,83); // prdt interrupt for entry 0
/// setup_pio_read_identify_command_multi4(1,27,64,83); // prdt interrupt for entry 0 /// setup_pio_read_identify_command_multi4(1,27,64,83); // prdt interrupt for entry 0
setup_pio_read_identify_command_multi4(1,64,63,64); // prdt interrupt for entry 0 /// setup_pio_read_identify_command_multi4(1,64,63,64); // prdt interrupt for entry 0 // last used
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR"); maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
`ifdef TEST_ABORT_COMMAND `ifdef TEST_ABORT_COMMAND
// Abort command by clearing ST // Abort command by clearing ST
...@@ -1080,6 +1103,15 @@ initial begin //Host ...@@ -1080,6 +1103,15 @@ initial begin //Host
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt
maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear global interrupts maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear global interrupts
wait (~IRQ); wait (~IRQ);
// Reset command with abort_dma
maxigp1_writep (HBA_PORT__PxCMD__FRE__ADDR << 2, HBA_PORT__PxCMD__FRE__MASK); // ST: 1 -> 0
repeat (50) @(posedge CLK);
maxigp1_writep (HBA_PORT__PxCMD__FRE__ADDR << 2, HBA_PORT__PxCMD__FRE__MASK |HBA_PORT__PxCMD__ST__MASK); // ST: 0 -> 1
// Print datascope - contents of the last CFIS sent // Print datascope - contents of the last CFIS sent
maxigp1_print ('h1000,"DATASCOPE 0"); // maxigp1_print ('h1000,"DATASCOPE 0"); //
maxigp1_print ('h1004,"DATASCOPE 1"); // maxigp1_print ('h1004,"DATASCOPE 1"); //
...@@ -1093,6 +1125,28 @@ initial begin //Host ...@@ -1093,6 +1125,28 @@ initial begin //Host
// sysmem_print ('h1e81,'h180); // for shifted // sysmem_print ('h1e81,'h180); // for shifted
sysmem_print ('h1e80,'h180); // Compact dump of "system memory" in hex word format sysmem_print ('h1e80,'h180); // Compact dump of "system memory" in hex word format
// Second time read identify:
// Prepare for D2H register FIS with interrupt bit set (expected to be sent after all data will be written to the device)
maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, HBA_PORT__PxIS__DHRS__MASK); // clear DHR (D2H register FIS with "I" bit) interrupt
maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__DHRE__MASK); // allow only D2H Register interrupts
maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear global interrupts for port 0 (the only one)
wait (~IRQ);
setup_pio_read_identify_command_simple(512,1); // prdt interrupt for entry 0
maxigp1_print (HBA_PORT__PxCI__CI__ADDR << 2,"HBA_PORT__PxCI__CI__ADDR");
maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__PSE__MASK); // allow PS only interrupts (PIO setup)
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear that interrupt
wait (IRQ);
TESTBENCH_TITLE = "Got second Identify";
$display("[Testbench]: %s @%t", TESTBENCH_TITLE, $time);
maxigp1_print (HBA_PORT__PxIS__PSS__ADDR << 2,"HBA_PORT__PxIS__PSS__ADDR");
maxigp1_writep (HBA_PORT__PxIS__PSS__ADDR << 2, HBA_PORT__PxIS__PSS__MASK); // clear PS interrupt
maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear global interrupts
wait (~IRQ);
// end of the second identify insertion
// Prepare for D2H register FIS with interrupt bit set (expected to be sent after all data will be written to the device) // Prepare for D2H register FIS with interrupt bit set (expected to be sent after all data will be written to the device)
maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, HBA_PORT__PxIS__DHRS__MASK); // clear DHR (D2H register FIS with "I" bit) interrupt maxigp1_writep (HBA_PORT__PxIS__DHRS__ADDR << 2, HBA_PORT__PxIS__DHRS__MASK); // clear DHR (D2H register FIS with "I" bit) interrupt
maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__DHRE__MASK); // allow only D2H Register interrupts maxigp1_writep (HBA_PORT__PxIE__PSE__ADDR << 2, HBA_PORT__PxIE__DHRE__MASK); // allow only D2H Register interrupts
......
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