Commit 09c87c41 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

v13: tolerating elidle from device during comreset/cominit (when device changes data rate)

parent 2d285422
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@ com.elphel.store.context.iverilog=iverilog_@_TopModulesOther<-@\#\#@->iverilog_@
com.elphel.store.version.iverilog=1.1
com.elphel.store.version.iverilog=1.1
eclipse.preferences.version=1
eclipse.preferences.version=1
iverilog_@_ExtraFiles=x393/glbl.v<-@\#\#@->
iverilog_@_ExtraFiles=x393/glbl.v<-@\#\#@->
iverilog_@_GTKWaveSavFile=tb_ahci_01.sav
iverilog_@_GTKWaveSavFile=tb_ahci_06.sav
iverilog_@_GrepFindErrWarn=error|warning|sorry
iverilog_@_GrepFindErrWarn=error|warning|sorry
iverilog_@_IcarusTopFile=tb/tb_ahci.tf
iverilog_@_IcarusTopFile=tb/tb_ahci.tf
iverilog_@_IncludeDir=${verilog_project_loc}/x393<-@\#\#@->${verilog_project_loc}/x393/includes<-@\#\#@->${verilog_project_loc}/host<-@\#\#@->${verilog_project_loc}/tb<-@\#\#@->
iverilog_@_IncludeDir=${verilog_project_loc}/x393<-@\#\#@->${verilog_project_loc}/x393/includes<-@\#\#@->${verilog_project_loc}/host<-@\#\#@->${verilog_project_loc}/tb<-@\#\#@->
+37 −3
Original line number Original line Diff line number Diff line
@@ -44,7 +44,10 @@
// All references to doc = to SerialATA_Revision_2_6_Gold.pdf
// All references to doc = to SerialATA_Revision_2_6_Gold.pdf
module oob_dev #(
module oob_dev #(
    parameter DATA_BYTE_WIDTH = 4,
    parameter DATA_BYTE_WIDTH = 4,
    parameter CLK_SPEED_GRADE = 2 // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
    parameter CLK_SPEED_GRADE = 2, // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
    parameter TEST_ELIDLE =      2,      // test transmitting eidle between data rates (number of times)
    parameter ELIDLE_DELAY =    'h28, // 80,    // counter cycles
    parameter ELIDLE_DURATION = 'h80    // counter cycles
)
)
(
(
    // sata clk = usrclk2
    // sata clk = usrclk2
@@ -83,15 +86,21 @@ localparam STATE_CALIBRATE = 4;
localparam  STATE_COMWAKE           = 5;
localparam  STATE_COMWAKE           = 5;
localparam  STATE_RECAL             = 55;
localparam  STATE_RECAL             = 55;
localparam  STATE_SENDALIGN         = 6;
localparam  STATE_SENDALIGN         = 6;
localparam  STATE_EIDLE_RATE        = 65; 
localparam  STATE_READY             = 7;
localparam  STATE_READY             = 7;
localparam  STATE_PARTIAL           = 8;
localparam  STATE_PARTIAL           = 8;
localparam  STATE_SLUMBER           = 9;
localparam  STATE_SLUMBER           = 9;
localparam  STATE_REDUCESPEED       = 10;
localparam  STATE_REDUCESPEED       = 10;
localparam  STATE_ERROR             = 11;
localparam  STATE_ERROR             = 11;



reg     [31:0]  rate_change_cntr;
reg             was_txelecidle;
reg     [9:0]   state;
reg     [9:0]   state;
wire    retry_interval_elapsed;
wire    retry_interval_elapsed;
wire    wait_interval_elapsed;
wire    wait_interval_elapsed;
wire    elidle_rate_delay_elapsed; 
wire    elidle_rate_duration_elapsed; 
wire    nocomwake;
wire    nocomwake;
wire    [31:0]  align;
wire    [31:0]  align;
wire    [31:0]  sync;
wire    [31:0]  sync;
@@ -111,8 +120,20 @@ always @ (posedge clk)


reg [31:0]  wait_timer;
reg [31:0]  wait_timer;
assign  wait_interval_elapsed =   wait_timer == 32'd4096;
assign  wait_interval_elapsed =   wait_timer == 32'd4096;
assign elidle_rate_delay_elapsed = wait_timer == ELIDLE_DELAY;
always @ (posedge clk)
always @ (posedge clk)
    wait_timer <= rst | ~(state == STATE_SENDALIGN) ? 32'h0 : wait_timer + 1'b1;
    wait_timer <= rst | ~(state == STATE_SENDALIGN) ? 32'h0 : wait_timer + 1'b1;
reg [31:0] elidle_timer;
assign elidle_rate_duration_elapsed = elidle_timer == ELIDLE_DURATION;    
always @ (posedge clk)
    elidle_timer <= rst | ~(state == STATE_EIDLE_RATE) ? 32'h0 : elidle_timer + 1'b1;

always @ (posedge clk) begin
    was_txelecidle <= txelecidle;
    if (rst)                                rate_change_cntr <= 0;
    else if (txelecidle && !was_txelecidle) rate_change_cntr <= rate_change_cntr + 1;  
end



reg [31:0]  data;
reg [31:0]  data;
reg [3:0]   isk;
reg [3:0]   isk;
@@ -218,6 +239,7 @@ always @ (posedge clk)
        end
        end
        STATE_SENDALIGN:
        STATE_SENDALIGN:
        begin
        begin
            txelecidle <= 1'b0;
            data    <= align;
            data    <= align;
            isk     <= 4'h1;
            isk     <= 4'h1;
            if (aligndet)
            if (aligndet)
@@ -225,9 +247,21 @@ always @ (posedge clk)
            else 
            else 
            if (wait_interval_elapsed)
            if (wait_interval_elapsed)
                state   <= STATE_ERROR;
                state   <= STATE_ERROR;
            else if ((rate_change_cntr < TEST_ELIDLE) && elidle_rate_delay_elapsed)
                state   <= STATE_EIDLE_RATE;
            else 
            else 
                state   <= STATE_SENDALIGN;
                state   <= STATE_SENDALIGN;
        end
        end

        STATE_EIDLE_RATE:
        begin
            txelecidle <= 1'b1;
            data    <= 0; // align; // 'bz;
            isk     <= 4'h1;
            if (elidle_rate_duration_elapsed)
                state   <= STATE_SENDALIGN;
        end
        
        STATE_READY:
        STATE_READY:
        begin
        begin
            txelecidle <= 1'b0;
            txelecidle <= 1'b0;
+27 −9
Original line number Original line Diff line number Diff line
@@ -223,7 +223,11 @@ always @ (posedge clk) begin
    else                         rxdlysreset_r <= rxdlysreset_r << 1; 
    else                         rxdlysreset_r <= rxdlysreset_r << 1; 
end
end



reg was_rxelecidle_waiting_reset;
always @ (posedge clk) begin
    if      (rst || set_wait_eidle)          was_rxelecidle_waiting_reset <= 0;
    else if (state_wait_rxrst && rxelecidle) was_rxelecidle_waiting_reset <= 1;
end
assign  state_idle = ~state_wait_cominit &
assign  state_idle = ~state_wait_cominit &
                     ~state_wait_comwake &
                     ~state_wait_comwake &
                     ~state_wait_align &
                     ~state_wait_align &
@@ -253,11 +257,17 @@ end
assign  set_wait_cominit   = state_idle & oob_start & ~cominit_req;
assign  set_wait_cominit   = state_idle & oob_start & ~cominit_req;
assign  set_wait_comwake   = state_idle & cominit_req_l & cominit_allow & rxcominit_done | state_wait_cominit & rxcominitdet_l & rxcominit_done;
assign  set_wait_comwake   = state_idle & cominit_req_l & cominit_allow & rxcominit_done | state_wait_cominit & rxcominitdet_l & rxcominit_done;
assign  set_recal_tx       = state_wait_comwake & rxcomwakedet_l & rxcomwake_done;
assign  set_recal_tx       = state_wait_comwake & rxcomwakedet_l & rxcomwake_done;
assign  set_wait_eidle     = state_recal_tx & recal_tx_done;
///assign  set_wait_eidle     = state_recal_tx & recal_tx_done;
assign  set_wait_eidle     = (state_recal_tx & recal_tx_done) |
                             (rxelecidle & 
                              (state_wait_align | state_wait_clk_align | state_wait_align2 | (state_wait_rxrst & rxreset_ack & was_rxelecidle_waiting_reset) ));
assign  set_wait_rxrst     = state_wait_eidle & eidle_timer_done;
assign  set_wait_rxrst     = state_wait_eidle & eidle_timer_done;
assign  set_wait_align     = state_wait_rxrst & rxreset_ack;
///assign  set_wait_align     = state_wait_rxrst & rxreset_ack;
assign  set_wait_clk_align = state_wait_align & (detected_alignp_r);
///assign  set_wait_clk_align = state_wait_align & (detected_alignp_r);
assign  set_wait_align2    = state_wait_clk_align & clk_phase_align_ack;
///assign  set_wait_align2    = state_wait_clk_align & clk_phase_align_ack;
assign  set_wait_align     = state_wait_rxrst & rxreset_ack & ~rxelecidle;
assign  set_wait_clk_align = state_wait_align & (detected_alignp_r) & ~rxelecidle;
assign  set_wait_align2    = state_wait_clk_align & clk_phase_align_ack & ~rxelecidle;






@@ -278,10 +288,18 @@ assign clr_wait_cominit = set_wait_comwake | set_error;
assign  clr_wait_comwake   = set_recal_tx       | set_error;
assign  clr_wait_comwake   = set_recal_tx       | set_error;
assign  clr_recal_tx       = set_wait_eidle     | set_error;
assign  clr_recal_tx       = set_wait_eidle     | set_error;
assign  clr_wait_eidle     = set_wait_rxrst     | set_error;
assign  clr_wait_eidle     = set_wait_rxrst     | set_error;
assign  clr_wait_rxrst     = set_wait_align     | set_error;
///assign  clr_wait_rxrst     = set_wait_align     | set_error;
assign  clr_wait_align     = set_wait_clk_align | set_error;
assign  clr_wait_rxrst     = state_wait_rxrst & rxreset_ack; 
assign  clr_wait_clk_align = set_wait_align2    | set_error;

assign  clr_wait_align2    = set_wait_synp      | set_error;
///assign  clr_wait_align     = set_wait_clk_align | set_error;
///assign  clr_wait_clk_align = set_wait_align2    | set_error;
///assign  clr_wait_align2    = set_wait_synp      | set_error;
assign  clr_wait_align     = set_wait_clk_align | set_error | rxelecidle;
assign  clr_wait_clk_align = set_wait_align2    | set_error | rxelecidle;
assign  clr_wait_align2    = set_wait_synp      | set_error | rxelecidle;



assign  clr_wait_synp      = set_wait_linkup    | set_error;
assign  clr_wait_synp      = set_wait_linkup    | set_error;
assign  clr_wait_linkup    = state_wait_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives
assign  clr_wait_linkup    = state_wait_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives
assign  clr_error          = state_error;
assign  clr_error          = state_error;
+1 −1
Original line number Original line Diff line number Diff line
@@ -2,6 +2,6 @@
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000)
, .INIT_0C (256'h000000000000000000000000000000000000000001010012001000000001FFFE)
, .INIT_0C (256'h000000000000000000000000000000000000000001010013001000000001FFFE)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
+1 −1
Original line number Original line Diff line number Diff line
@@ -97,7 +97,7 @@
// RO: HBA Revision ID
// RO: HBA Revision ID
    localparam PCI_Header__RID__RID__ADDR = 'h62;
    localparam PCI_Header__RID__RID__ADDR = 'h62;
    localparam PCI_Header__RID__RID__MASK = 'hff;
    localparam PCI_Header__RID__RID__MASK = 'hff;
    localparam PCI_Header__RID__RID__DFLT = 'h12;
    localparam PCI_Header__RID__RID__DFLT = 'h13;
// RO: Base Class Code: 1 - Mass Storage Device
// RO: Base Class Code: 1 - Mass Storage Device
    localparam PCI_Header__CC__BCC__ADDR = 'h62;
    localparam PCI_Header__CC__BCC__ADDR = 'h62;
    localparam PCI_Header__CC__BCC__MASK = 'hff000000;
    localparam PCI_Header__CC__BCC__MASK = 'hff000000;
Loading