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

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

parent 2d285422
......@@ -2,7 +2,7 @@ com.elphel.store.context.iverilog=iverilog_@_TopModulesOther<-@\#\#@->iverilog_@
com.elphel.store.version.iverilog=1.1
eclipse.preferences.version=1
iverilog_@_ExtraFiles=x393/glbl.v<-@\#\#@->
iverilog_@_GTKWaveSavFile=tb_ahci_01.sav
iverilog_@_GTKWaveSavFile=tb_ahci_06.sav
iverilog_@_GrepFindErrWarn=error|warning|sorry
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<-@\#\#@->
......
......@@ -44,7 +44,10 @@
// All references to doc = to SerialATA_Revision_2_6_Gold.pdf
module oob_dev #(
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
......@@ -83,15 +86,21 @@ localparam STATE_CALIBRATE = 4;
localparam STATE_COMWAKE = 5;
localparam STATE_RECAL = 55;
localparam STATE_SENDALIGN = 6;
localparam STATE_EIDLE_RATE = 65;
localparam STATE_READY = 7;
localparam STATE_PARTIAL = 8;
localparam STATE_SLUMBER = 9;
localparam STATE_REDUCESPEED = 10;
localparam STATE_ERROR = 11;
reg [31:0] rate_change_cntr;
reg was_txelecidle;
reg [9:0] state;
wire retry_interval_elapsed;
wire wait_interval_elapsed;
wire elidle_rate_delay_elapsed;
wire elidle_rate_duration_elapsed;
wire nocomwake;
wire [31:0] align;
wire [31:0] sync;
......@@ -110,9 +119,21 @@ always @ (posedge clk)
retry_timer <= rst | ~(state == STATE_AWAITCOMWAKE) ? 32'h0 : retry_timer + 1'b1;
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)
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 [3:0] isk;
......@@ -218,6 +239,7 @@ always @ (posedge clk)
end
STATE_SENDALIGN:
begin
txelecidle <= 1'b0;
data <= align;
isk <= 4'h1;
if (aligndet)
......@@ -225,9 +247,21 @@ always @ (posedge clk)
else
if (wait_interval_elapsed)
state <= STATE_ERROR;
else
else if ((rate_change_cntr < TEST_ELIDLE) && elidle_rate_delay_elapsed)
state <= STATE_EIDLE_RATE;
else
state <= STATE_SENDALIGN;
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:
begin
txelecidle <= 1'b0;
......
......@@ -223,7 +223,11 @@ always @ (posedge clk) begin
else rxdlysreset_r <= rxdlysreset_r << 1;
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 &
~state_wait_comwake &
~state_wait_align &
......@@ -253,11 +257,17 @@ end
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_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_align = state_wait_rxrst & rxreset_ack;
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_align = state_wait_rxrst & rxreset_ack;
///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_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_recal_tx = set_wait_eidle | set_error;
assign clr_wait_eidle = set_wait_rxrst | set_error;
assign clr_wait_rxrst = set_wait_align | 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_rxrst = set_wait_align | set_error;
assign clr_wait_rxrst = state_wait_rxrst & rxreset_ack;
///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_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;
......
......@@ -2,6 +2,6 @@
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000)
, .INIT_0C (256'h000000000000000000000000000000000000000001010012001000000001FFFE)
, .INIT_0C (256'h000000000000000000000000000000000000000001010013001000000001FFFE)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
......@@ -97,7 +97,7 @@
// RO: HBA Revision ID
localparam PCI_Header__RID__RID__ADDR = 'h62;
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
localparam PCI_Header__CC__BCC__ADDR = 'h62;
localparam PCI_Header__CC__BCC__MASK = 'hff000000;
......
......@@ -537,6 +537,8 @@
parameter SENS_SS_MODE = "CENTER_HIGH",//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter SENS_SS_MOD_PERIOD = 10000, // integer 4000-40000 - SS modulation period in ns
parameter CMPRS_CHN_MASK = 4'hf, // specify wich compressor channels to use (disable some/all to make room for processing)
parameter CMPRS_NUM_AFI_CHN = 1, // 2, // 1 - multiplex all 4 compressors to a single AXI_HP, 2 - split between to AXI_HP
parameter CMPRS_GROUP_ADDR = 'h600, // total of 'h60
parameter CMPRS_BASE_INC = 'h10,
......
......@@ -32,7 +32,8 @@ __status__ = "Development"
**** Modify next value for new file versions, re-run this file *****
"""
# Revision ID
RID = 0x012 # Revision ID: registering irq on/off in datascope, as if tag = 6/7
RID = 0x013 # Revision ID: tolerating elidle during OOB sequence (when device changes data rate)
#RID = 0x012 # Revision ID: registering irq on/off in datascope, as if tag = 6/7
#RID = 0x011 # Revision ID
VID = 0xfffe # What to use for non-PCI "vendorID"?
DID = 0x0001
......
......@@ -694,6 +694,7 @@ class x393sata(object):
if do_not_start:
print ('Run the following command to start the comand:')
print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)")
return
else:
self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1)
print("Command table data:")
......
This diff is collapsed.
This diff is collapsed.
No preview for this file type
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