Commit 507b1bd3 authored by Andrey Filippov's avatar Andrey Filippov

more testing with DRP

parent d7e78d92
......@@ -52,87 +52,87 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoOpt.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoOptPower.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoPlace.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoRoute.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160208171112129.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160209233314772.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160208171112129.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160209233314772.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160208171331975.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160209233437529.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160208171112129.log</location>
<location>/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160209233314772.log</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-phys.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160208171331975.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160209233437529.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt-power.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160208171331975.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160209233437529.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-opt.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160208171331975.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160209233437529.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-place.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160208171331975.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160209233437529.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-route.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160208171331975.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160209233437529.dcp</location>
</link>
<link>
<name>vivado_state/x393_sata-synth.dcp</name>
<type>1</type>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160208171112129.dcp</location>
<location>/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160209233314772.dcp</location>
</link>
</linkedResources>
</projectDescription>
......@@ -273,6 +273,7 @@ module ahci_dma (
reg abort_rq_mclk;
reg abort_busy_mclk;
wire [21:0] abort_debug;
reg rwaddr_rq_r; // next cycle after requesting waddr_data_rq, raddr_data_rq, raddr_ct_rq and raddr_prd_rq (*-pend is valid)
assign afi_wvalid = aborting ? afi_wvalid_abort: afi_wvalid_data;
assign afi_wid = aborting ? afi_wid_abort: afi_id;
......@@ -380,6 +381,9 @@ module ahci_dma (
always @ (posedge hclk) begin
hrst_r <= hrst;
if (hrst) rwaddr_rq_r <= 0;
else rwaddr_rq_r <= raddr_ct_rq || raddr_prd_rq || raddr_data_rq || waddr_data_rq;
addr_data_rq_r <= addr_data_rq_w;
prd_start_hclk_r <= prd_start_hclk;
......@@ -414,7 +418,9 @@ module ahci_dma (
if (hrst) {is_ct_addr, is_prd_addr, is_data_addr} <= 0;
else if (raddr_ct_rq || raddr_prd_rq || wcount_set) {is_ct_addr, is_prd_addr, is_data_addr} <= {raddr_ct_rq, raddr_prd_rq, wcount_set};
if (axi_set_raddr_w || axi_set_waddr_w) begin
/// if (axi_set_raddr_w || axi_set_waddr_w) begin
if (rwaddr_rq_r) begin // first cycle one of the *_pend is set
if (raddr_data_pend || waddr_data_pend) afi_addr <= {data_addr[31:3], 3'b0};
else afi_addr <= {ct_maddr[31:4], 4'b0};
......
......@@ -266,11 +266,12 @@ module ahci_fsm
// 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 ||
wire fsm_act_done_w = get_fis_done ||
xmit_done ||
(syncesc_send_pend && syncesc_send_done) ||
dma_abort_done ||
asynq_rq; // cominit_got || pcmd_st_cleared
reg fsm_act_done; // made later by 1 cycle so the new conditions are latched
wire fsm_wait_act_w = pgm_data[16]; // this action requires waiting for done
wire fsm_last_act_w = pgm_data[17];
......@@ -339,6 +340,8 @@ module ahci_fsm
else if (fsm_transitions[0] && (!cond_met_w || !fsm_transitions[1])) pgm_jump_addr <= pgm_data[9:0];
was_rst <= hba_rst;
fsm_act_done <= fsm_act_done_w; // delay by 1 clock cycle
fsm_jump <= {fsm_jump[1:0], pre_jump_w | (was_rst & ~hba_rst)};
......
......@@ -91,6 +91,16 @@ module ahci_sata_layers #(
output wire txn_out,
input wire rxp_in,
input wire rxn_in,
`ifdef USE_DRP
input drp_rst,
input drp_clk,
input drp_en, // @aclk strobes drp_ad
input drp_we,
input [14:0] drp_addr,
input [15:0] drp_di,
output drp_rdy,
output [15:0] drp_do ,
`endif
output [31:0] debug_phy,
output [31:0] debug_link
......@@ -338,7 +348,17 @@ module ahci_sata_layers #(
.cplllock_debug (),
.usrpll_locked_debug(),
`ifdef USE_DRP
.drp_rst (drp_rst), // input
.drp_clk (drp_clk), // input
.drp_en (drp_en), // input
.drp_we (drp_we), // input
.drp_addr (drp_addr), // input[14:0]
.drp_di (drp_di), // input[15:0]
.drp_rdy (drp_rdy), // output
.drp_do (drp_do), // output[15:0]
`endif
.debug_sata (debug_phy)
,.debug_detected_alignp(debug_detected_alignp)
);
......
......@@ -182,6 +182,14 @@ module ahci_top#(
output irq, // CPU interrupt request
`ifdef USE_DRP
output drp_en, // @aclk strobes drp_ad
output drp_we,
output [14:0] drp_addr,
output [15:0] drp_di,
input drp_rdy,
input [15:0] drp_do,
`endif
input [31:0] debug_in_phy,
input [31:0] debug_in_link
......@@ -705,9 +713,19 @@ module ahci_top#(
.was_hba_rst (was_hba_rst), // output
.was_port_rst (was_port_rst), // output
.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_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_DRP
,.drp_en (drp_en), // output reg
.drp_we (drp_we), // output reg
.drp_addr (drp_addr), // output[14:0] reg
.drp_di (drp_di), // output[15:0] reg
.drp_rdy (drp_rdy), // input
.drp_do (drp_do) // input[15:0]
`endif
`ifdef USE_DATASCOPE
,.datascope_clk (datascope_clk), // input
.datascope_waddr (datascope_waddr), // input[9:0]
......@@ -977,7 +995,7 @@ wire [9:0] xmit_dbg_01;
// .hba_rst (mrst), // input TODO: Reset when !PxCMD.ST? pcmd_st
.hba_rst (mrst || !pcmd_st), // input TODO: Reset when !PxCMD.ST? pcmd_st
.mclk (mclk), // input
.pcmd_st_cleared (pcmd_st_cleared), // input
.fetch_cmd (fsnd_fetch_cmd), // input
.cfis_xmit (fsnd_cfis_xmit), // input
.dx_xmit (fsnd_dx_xmit), // input
......
......@@ -119,6 +119,14 @@ module axi_ahci_regs#(
input [31:0] debug_in1,
input [31:0] debug_in2,
input [31:0] debug_in3
`ifdef USE_DRP
,output reg drp_en, // @aclk strobes drp_ad
output reg drp_we,
output reg [14:0] drp_addr,
output reg [15:0] drp_di,
input drp_rdy,
input [15:0] drp_do
`endif
`ifdef USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
,input datascope_clk,
......@@ -127,6 +135,12 @@ module axi_ahci_regs#(
input [31:0] datascope_di
`endif
);
`ifdef USE_DRP
localparam DRP_ADDR = 'h3fb;
reg [15:0] drp_read_data;
reg drp_read_r;
reg drp_ready_r;
`endif
`ifdef USE_DATASCOPE
localparam AXIBRAM_BITS = ADDRESS_BITS + 1; // number of axi address outputs (one more than ADDRESS_BITS when using datascope)
wire [31:0] datascope_rdata;
......@@ -202,7 +216,27 @@ module axi_ahci_regs#(
assign was_hba_rst = was_hba_rst_r[0];
assign was_port_rst = was_port_rst_r[0];
always @(posedge aclk) begin
`ifdef USE_DRP
if (bram_waddr == DRP_ADDR) begin
drp_di <= bram_wdata[15: 0];
drp_addr <= bram_wdata[30:16];
// drp_we <= bram_wdata[31];
end
drp_en <= (bram_waddr == DRP_ADDR);
drp_we <= (bram_waddr == DRP_ADDR) && bram_wdata[31];
if (arst || (bram_waddr == DRP_ADDR)) drp_ready_r <= 0;
else if (drp_rdy) drp_ready_r <= 1;
if (drp_rdy) drp_read_data <= drp_do;
if (bram_ren[0]) drp_read_r <= (bram_raddr == DRP_ADDR);
`endif
if (arst) write_busy_r <= 0;
else if (write_start_burst) write_busy_r <= 1;
......@@ -210,21 +244,30 @@ module axi_ahci_regs#(
if (bram_wen) bram_wdata_r <= bram_wdata;
// if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_in : bram_rdata;
bram_wstb_r <= {4{bram_wen}} & bram_wstb;
bram_wen_r <= bram_wen;
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)
`ifdef USE_DATASCOPE
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]) &&
// (bram_raddr[3:2] == 0) &&
!bram_raddr[ADDRESS_BITS]; //
`else
if (bram_ren[0]) debug_rd_r <= (&bram_raddr[ADDRESS_BITS-1:4]); // &&
// (bram_raddr[3:2] == 0); //
`endif
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;
`ifdef USE_DRP
if (bram_ren[1]) bram_rdata_r <= drp_read_r? {drp_ready_r, 15'b0,drp_read_data}:
(debug_rd_r? debug_r : bram_rdata);
`else
if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_r : bram_rdata;
`endif
end
//debug_rd_r
......@@ -415,12 +458,9 @@ sata_phy_rst_out will be released after the sata clock is stable
) ahci_regs_i (
.clk_a (aclk), // input
.addr_a (bram_addr), // input[9:0]
/// .en_a (bram_ren[0] || write_busy_w), // input
.en_a (bram_ren[0] || bram_wen || bram_wen_r), // input
/// .en_a (bram_ren_w[0] || bram_wen || bram_wen_r), // input
.regen_a (1'b0), // input
// .we_a (write_busy_r && !nowrite), // input
.we_a (bram_wstb_r), //bram_wen_d), // input[3:0]
.we_a (bram_wstb_r), // input[3:0]
//
.data_out_a (bram_rdata), // output[31:0]
.data_in_a (ahci_regs_di), // input[31:0]
......
......@@ -43,14 +43,14 @@
parameter HBA_RESET_BITS = 9, // duration of HBA reset in aclk periods (9: ~10usec)
parameter RESET_TO_FIRST_ACCESS = 1 // keep port reset until first R/W any register by software
)(
output wire sata_clk,
output wire sata_rst,
input wire arst, // extrst,
output wire sata_clk,
output wire sata_rst,
input wire arst, // extrst,
// reliable clock to source drp and cpll lock det circuits
input wire reliable_clk,
input wire reliable_clk,
input wire hclk,
input wire hclk,
/*
* Commands interface
......@@ -224,6 +224,16 @@
reg [2:0] nhrst_r;
wire hrst = !nhrst_r[2];
`ifdef USE_DRP
wire drp_en;
wire drp_we;
wire [14:0] drp_addr;
wire [15:0] drp_di;
wire drp_rdy;
wire [15:0] drp_do;
`endif
wire [31:0] debug_phy;
wire [31:0] debug_link;
......@@ -366,6 +376,14 @@
.sctl_ipm (sctl_ipm), // output[3:0]
.sctl_spd (sctl_spd), // output[3:0]
.irq (irq), // output
`ifdef USE_DRP
.drp_en (drp_en), // output reg
.drp_we (drp_we), // output reg
.drp_addr (drp_addr), // output[14:0] reg
.drp_di (drp_di), // output[15:0] reg
.drp_rdy (drp_rdy), // input
.drp_do (drp_do), // input[15:0]
`endif
.debug_in_phy (debug_phy), // input[31:0]
.debug_in_link (debug_link) // input[31:0]
);
......@@ -425,7 +443,17 @@
.txp_out (TXP), // output wire
.txn_out (TXN), // output wire
.rxp_in (RXP), // input wire
.rxn_in (RXN), // input wire
.rxn_in (RXN), // input wire
`ifdef USE_DRP
.drp_rst (arst), // input
.drp_clk (ACLK), // input
.drp_en (drp_en), // input
.drp_we (drp_we), // input
.drp_addr (drp_addr), // input[14:0]
.drp_di (drp_di), // input[15:0]
.drp_rdy (drp_rdy), // output
.drp_do (drp_do), // output[15:0]
`endif
.debug_phy (debug_phy), // output[31:0]
.debug_link (debug_link) // output[31:0]
);
......
This diff is collapsed.
......@@ -82,6 +82,16 @@ module sata_phy #(
output cplllock_debug,
output usrpll_locked_debug,
`ifdef USE_DRP
input drp_rst,
input drp_clk,
input drp_en, // @aclk strobes drp_ad
input drp_we,
input [14:0] drp_addr,
input [15:0] drp_di,
output drp_rdy,
output [15:0] drp_do,
`endif
output [31:0] debug_sata
,output debug_detected_alignp
......@@ -519,6 +529,17 @@ gtx_wrap
.dbg_rxcdrlock (dbg_rxcdrlock) ,
.dbg_rxdlysresetdone(dbg_rxdlysresetdone),
.txbufstatus (txbufstatus[1:0])
`ifdef USE_DRP
,.drp_rst (drp_rst), // input
.drp_clk (drp_clk), // input
.drp_en (drp_en), // input
.drp_we (drp_we), // input
.drp_addr (drp_addr), // input[14:0]
.drp_di (drp_di), // input[15:0]
.drp_rdy (drp_rdy), // output
.drp_do (drp_do) // output[15:0]
`endif
);
......
/*******************************************************************************
* Module: sipo_to_xclk_measure
* Date:2016-02-09
* Author: andrey
* Description: Measuring phase of the SIPO data output relative to (global) xclk
* This module allow select all/some of the input data lines and see if the data
* sampled at negedge of the xclk differs from sampled at the previous or next
* posedge on any of the selected bits. Mismatch with previous posedge means that
* data comes while xclk == 0 (input data too late), mismatch with next posedge
* means that data changes while xclk == 1 (too early).
* Input selection for low 16 bits is written at address DRP_MASK_ADDR (0), next
* 16 bits - at DRP_MASK_ADDR + 1.
* Measurement starts by writing duration to DRP_TIMER_ADDR (8).
* Results (number of mismatches) are available as 15-bit numbers at
* DRP_EARLY_ADDR (9) and DRP_LATE_ADDR (10), MSB indicates that measurement is
* still in progress (wait it clears, small latency for 0 -> 1 should not be
* a problem).
*
* Copyright (c) 2016 Elphel, Inc .
* sipo_to_xclk_measure.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.
*
* sipo_to_xclk_measure.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 sipo_to_xclk_measure#(
parameter DATA_WIDTH = 20, // Number of data bits to measure
parameter DRP_ABITS = 8,
parameter DRP_MASK_ADDR = 0,
parameter DRP_MASK_BITS = 3,
parameter DRP_TIMER_ADDR = 8, // write timer value (how long to count early/late)
parameter DRP_EARLY_ADDR = 9, // write timer value (how long to count early/late)
parameter DRP_LATE_ADDR = 10, // write timer value (how long to count early/late)
parameter DRP_OTHERCTRL_ADDR = 11
)(
input xclk,
input drp_rst, // for other_control
input [DATA_WIDTH-1:0] sipo_di,
output [DATA_WIDTH-1:0] sipo_do, // input data registered @ posedge xclk (to be used by other modules)
input drp_clk,
input drp_en, // @aclk strobes drp_ad
input drp_we,
input [DRP_ABITS-1:0] drp_addr,
input [15:0] drp_di,
output reg drp_rdy,
output reg [15:0] drp_do,
output reg [15:0] other_control // set/reset some control bits not related to this module
);
localparam MASK_WORDS = (DATA_WIDTH + 15) >> 4;
reg [DATA_WIDTH-1:0] sipo_p; // input data registered @ posedge xclk
reg [DATA_WIDTH-1:0] sipo_n; // input data registered @ negedge xclk
reg [DATA_WIDTH-1:0] sipo_pp; // input data registered twice @ posedge xclk
reg [DATA_WIDTH-1:0] sipo_np; // input data registered @ negedge xclk, then @ posedge xclk
reg [(16 * MASK_WORDS) - 1:0] dmask; // bits to consider (or)
reg input_early_r; // SIPO data is intended to be registered @ posedge xclk
reg input_late_r;
reg [15:0] timer_cntr;
reg [14:0] early_cntr;
reg [14:0] late_cntr;
wire timer_start;
reg timer_run;
reg [DRP_ABITS-1:0] drp_addr_r;
reg drp_wr_r;
reg [ 1:0] drp_rd_r;
reg [15:0] drp_di_r;
reg drp_mask_wr;
reg drp_timer_wr;
reg drp_read_early;
reg drp_read_late;
reg drp_other_ctrl;
reg drp_read_other_ctrl;
localparam DRP_MASK_MASK = (1 << DRP_MASK_BITS) -1;
assign sipo_do = sipo_p;
always @ (negedge xclk) sipo_n <= sipo_di; // only data registered @negedge
always @ (posedge xclk) begin
sipo_p <= sipo_di;
sipo_np <= sipo_n;
sipo_pp <= sipo_p;
input_early_r <= |(dmask[DATA_WIDTH-1:0] & (sipo_np ^ sipo_pp));
input_late_r <= |(dmask[DATA_WIDTH-1:0] & (sipo_np ^ sipo_p));
if (timer_start) timer_cntr <= drp_di_r;
else if (timer_run) timer_cntr <= timer_cntr - 1;
if (timer_start) timer_run <= 1;
else if (!(|timer_cntr[15:1])) timer_run <= 0;
if (timer_start) early_cntr <= 0;
else if (timer_run && input_early_r) early_cntr <= early_cntr + 1;
if (timer_start) late_cntr <= 0;
else if (timer_run && input_late_r) late_cntr <= late_cntr + 1;
end
// DRP interface
always @ (posedge drp_clk) begin
drp_addr_r <= drp_addr;
drp_wr_r <= drp_we && drp_en;
drp_rd_r <= {drp_rd_r[0],~drp_we & drp_en};
drp_di_r <= drp_di;
drp_mask_wr <= drp_wr_r && ((drp_addr_r & ~DRP_MASK_MASK) == DRP_MASK_ADDR);
drp_timer_wr <= drp_wr_r && (drp_addr_r == DRP_TIMER_ADDR);
drp_read_early <= drp_rd_r[0] && (drp_addr_r == DRP_EARLY_ADDR);
drp_read_late <= drp_rd_r[0] && (drp_addr_r == DRP_LATE_ADDR);
drp_other_ctrl <= drp_wr_r && (drp_addr_r == DRP_OTHERCTRL_ADDR);
drp_read_other_ctrl <= drp_rd_r[0] && (drp_addr_r == DRP_OTHERCTRL_ADDR);
drp_rdy <= drp_wr_r || drp_rd_r[1];
drp_do <= ({16{drp_read_early}} & {timer_run,early_cntr}) |
({16{drp_read_late}} & {timer_run,late_cntr}) |
({16{drp_read_other_ctrl}} & {other_control}) ;
if (drp_rst) other_control <= 0;
else if (drp_other_ctrl) other_control <= drp_di_r;
end
// 0..7 - data mask
genvar i1;
generate
for (i1 = 0; i1 < MASK_WORDS; i1 = i1 + 1) begin: gen_drp_mask
always @ (posedge drp_clk)
if (drp_mask_wr && ((drp_addr_r & DRP_MASK_MASK) ==i1)) dmask[16*i1 +: 16] <= drp_di_r;
end
endgenerate
pulse_cross_clock #(
.EXTRA_DLY(0)
) timer_set_i (
.rst (drp_mask_wr), // input
.src_clk (drp_clk), // input
.dst_clk (xclk), // input
.in_pulse (drp_timer_wr), // input
.out_pulse (timer_start), // output
.busy() // output
);
endmodule
......@@ -62,7 +62,7 @@ COMMAND_BUFFER_OFFSET = 0x0 # Just at the beginning of available memory
COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 bytes each)
PRD_OFFSET = 0x80 # Start of the PRD table
FB_OFFS = 0xc00 # Needs 0x100 bytes
DRP_OFFS = 0xfec # Read/Write DRP data [31] - write/ready, [30:16] - address/0, [15:0] - data to/data from
DATAIN_BUFFER_OFFSET = 0x10000
DATAIN_BUFFER_SIZE = 0x10000
IDENTIFY_BUF = 0 # Identify receive buffer offset in DATAIN_BUFFER, in bytes
......@@ -79,6 +79,14 @@ COMMAND_ADDRESS = None # start of the command buffer (to be sent to device)
DATAIN_ADDRESS = None # start of the the
DATAOUT_ADDRESS = None # start of the the
#DRP addresses (non-GTX)
DRP_MASK_ADDR = 0x200 # ..0x207
DRP_TIMER_ADDR = 0x208 # write timer value (how long to count early/late)
DRP_EARLY_ADDR = 0x209 # write timer value (how long to count early/late)
DRP_LATE_ADDR = 0x20a # write timer value (how long to count early/late)
DRP_OTHERCTRL_ADDR = 0x20b # Now bit 0 - disable wait for phase align
#FIS types
FIS_H2DR = 0x27
FIS_D2HR = 0x34
......@@ -650,6 +658,44 @@ class x393sata(object):
#print("Memory read data:")
#print("_=mem.mem_dump (0x%x, 0x%x, 1)"%(data_buf, count * 0x200))
#self.x393_mem.mem_dump (data_buf, count * 0x200, 1)
def drp_write (self, addr, data):
self.x393_mem.write_mem(MAXI1_ADDR + DRP_OFFS, (1 << 31) | ((addr & 0x7fff) << 16) | (data & 0xffff))
# while (self.x393_mem.read_mem(MAXI1_ADDR + DRP_OFFS)) & (1 << 31): # No need to wait from Python
# sleep(0.001)
def drp_read (self, addr):
self.x393_mem.write_mem(MAXI1_ADDR + DRP_OFFS, (0 << 31) | ((addr & 0x7fff) << 16))
d = self.x393_mem.read_mem(MAXI1_ADDR + DRP_OFFS)
while not d & (1 << 31) :
d = self.x393_mem.read_mem(MAXI1_ADDR + DRP_OFFS)
return int(d & 0xffff)
def drp (self, addr, data=None):
if data is None:
return self.drp_read(addr)
self.drp_write (addr, data)
def read_sipo_meas(self, mask, duration):
self.drp_write (DRP_MASK_ADDR, mask & 0xffff)
self.drp_write (DRP_MASK_ADDR + 1, (mask >> 16) & 0xffff)
self.drp_write (DRP_TIMER_ADDR, duration)
early_count = self.drp_read(DRP_EARLY_ADDR)
while (early_count & (1 << 15)):
early_count = self.drp_read(DRP_EARLY_ADDR)
late_count = self.drp_read(DRP_LATE_ADDR)
print ("early_count = 0x%x, late_count = 0x%x, duration = 0x%x"%(early_count, late_count, duration))
return (1.0 * early_count/duration, 1.0 * late_count/duration)
def drp_cbit (self, bit, value=None):
old_val = self.drp_read (DRP_OTHERCTRL_ADDR)
if value is None:
return (old_val >> bit ) & 1;
mask = (1 << bit)
if value:
new_val = mask
else:
new_val = 0
self.drp_write (DRP_OTHERCTRL_ADDR, ((old_val ^ new_val) & mask) ^ old_val)
"""
ATA_IDFY = 0xec # Identify command
......@@ -663,12 +709,29 @@ ATA_RBUF_DMA = 0xe9 # Read 512 bytes from device buffer in DMA mode
_=mem.mem_dump(0xf800b000,10,4)
_=mem.mem_dump (0x80000ff0, 4,4)
sata.read_sipo_meas(0xfffff,0x7ffe)
mem.write_mem(0x80000118,0x11) # ST & FRE
Implement DRP read/write:
mem.write_mem(0x80000fec, 0x550000)
hex(mem.read_mem(0x80000fec))
'0x8000001fL'
sata.drp_write(0x20b,1) #disable wait for auto align
sata.reset_device()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status(
sata.reset_ie(), sata.reg_status()
sata.read_sipo_meas(0xfffff,0x7ffe)
drp_write ('h20b, 'h401); // bypass, clock align
sata.reg_status(),sata.reset_ie()
sata.read_sipo_meas(0xfffff,0x7ffe)
_=mem.mem_dump (0x80000ff0, 4,4)
hex(sata.drp_read(0x55))
cd /mnt/mmc/local/bin
python
......@@ -678,14 +741,18 @@ import x393sata
import x393_mem
mem = x393_mem.X393Mem(1,0,1)
sata = x393sata.x393sata()
sata.bitstream()
#sata.drp_write (0x20b,0x401) # bypass, clock align
### sata.drp (0x20b,0x81) # bypass, clock align
#sata.drp (0x20b,0x400) # bypass, clock align
### sata.drp (0x59,0x8) # Use RXREC
#sata.drp (0x59,0x48)
sata.reg_status()
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
mem.write_mem(0x80000118,0x11)
sata.reset_ie(), sata.reg_status()
sata.reg_status(),sata.reset_ie()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.setup_pio_read_identify_command()
sata.reg_status()
......@@ -737,6 +804,7 @@ sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x81, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
......@@ -744,6 +812,141 @@ sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x321, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x331, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x341, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x441, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x421, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x481, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x4c1, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x4f1, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x4ff, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x500, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x400, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x401, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x601, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x600, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x5ff, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x601, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x600, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x602, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
sata.reg_status()
sata.reset_ie()
sata.dd_read_dma(0x5f0, 1)
_=mem.mem_dump (0x80001000, 0x100,4)
sata.reg_status()
_=mem.mem_dump (0x80000ff0, 4,4)
mem.write_mem(0x80000118,0x10)
......@@ -766,7 +969,7 @@ hex(mem.read_mem(0x80000ff0))
mem.write_mem(0x80000118,0x11)
sata.setup_pio_read_identify_command()
mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)
#mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)
_=mem.mem_dump (0x80001000, 0x20,4)
mem.maxi_base()
......
// This file may be used to define same pre-processor macros to be included into each parsed file
`ifndef SYSTEM_DEFINES
`define SYSTEM_DEFINES
`define USE_DRP
`define ALIGN_CLOCKS
`define USE_DATASCOPE
`define PRELOAD_BRAMS
......
......@@ -714,6 +714,9 @@ always #(CLKIN_PERIOD/2) CLK = ~CLK;
`include "includes/ahci_localparams.vh" // SuppressThisWarning VEditor - many unused defines
`include "includes/fis_types.vh" // SuppressThisWarning VEditor - some unused defines
localparam MAXIGP1 = 32'h80000000; // Start of the MAXIGP1 address range (use ahci_localparams.vh offsets)
localparam DRP_OFFSET = 'hfec;
localparam DEBUG_OFFSET = 'hff0;
task maxigp1_write_single; // address in bytes, not words
input [31:0] address;
......@@ -732,7 +735,47 @@ localparam MAXIGP1 = 32'h80000000; // Start of the MAXIGP1 address range (use ah
end
endtask
task drp_write;
input [14:0] addr;
input [15:0] data;
begin
$display ("[DRP]: %x <- %x @ %t",addr, data,$time);
maxigp1_write_single (DRP_OFFSET, {1'b1, addr, data});
maxigp1_read (DRP_OFFSET);
while (!registered_rdata[31]) maxigp1_read (DRP_OFFSET);
end
endtask
task drp_read;
input [14:0] addr;
output reg [15:0] data;
begin
maxigp1_write_single (DRP_OFFSET, {1'b0, addr, 16'b0});
maxigp1_read (DRP_OFFSET);
while (!registered_rdata[31]) maxigp1_read (DRP_OFFSET);
data = registered_rdata[15:0];
$display ("[DRP]: %x -> %x @ %t",addr, data,$time);
end
endtask
task read_sipo_meas;
input [31:0] mask;
input [15:0] duration;
output reg [14:0] early_count;
output reg [14:0] late_count;
reg running;
// wire [15:0] data;
begin
drp_write ('h200, mask[15:0]);
drp_write ('h201, mask[31:16]);
drp_write ('h208, duration);
drp_read ('h209, {running,early_count});
drp_read ('h209, {running,early_count});
while (running) drp_read ('h209,{running, early_count});
drp_read ('h20a, {running, late_count});
$display ("[DRP] read_sipo_meas(): early:%x/%x, late: %x/%x @ %t",early_count,duration,late_count,duration,$time);
end
endtask
task maxigp1_read;
input [31:0] address;
......@@ -999,7 +1042,9 @@ localparam ATA_RBUF_DMA = 'he9; // Read 512 bytes from device buffer in DMA mod
reg [15:0] drp_read_data;
reg [14:0] early_count;
reg [14:0] late_count;
initial begin //Host
NUM_WORDS_EXPECTED =0;
......@@ -1010,6 +1055,21 @@ initial begin //Host
repeat (10) @ (posedge CLK);
axi_set_rd_lag(0);
axi_set_b_lag(0);
//simulate DRP write/read
// disable waiting for phase aligned:
// drp_write ('h20b, 'h400); // no-bypass, clock align
drp_write ('h20b, 'h401); // bypass, clock align
drp_write ('h10, 'h1234);
drp_write ('h11, 'h2345);
drp_write ('h12, 'h3456);
drp_read ('h10, drp_read_data);
drp_read ('h11, drp_read_data);
drp_read ('h12, drp_read_data);
drp_read ('h20b, drp_read_data);
maxigp1_writep (PXSIG_OFFS32 << 2, 'h12345678); //
maxigp1_writep (PXTFD_OFFS32 << 2, 'h87654321); //
......@@ -1045,6 +1105,17 @@ initial begin //Host
wait (IRQ);
TESTBENCH_TITLE = "Got D2H IRQ";
$display("[Testbench]: %s @%t", TESTBENCH_TITLE, $time);
maxigp1_print (DEBUG_OFFSET + 0, "DEBUG0");
maxigp1_print (DEBUG_OFFSET + 4, "DEBUG1");
maxigp1_print (DEBUG_OFFSET + 8 ,"DEBUG2");
maxigp1_print (DEBUG_OFFSET + 12, "DEBUG3");
read_sipo_meas ('hfffff, 256, early_count, late_count);
read_sipo_meas ('h00001, 256, early_count, late_count);
maxigp1_print (GHC__IS__IPS__ADDR << 2,"GHC__IS__IPS__ADDR"); // Should be 1 (port 0)
maxigp1_writep (GHC__IS__IPS__ADDR << 2, 1); // clear that interrupt
maxigp1_print (GHC__IS__IPS__ADDR << 2,"GHC__IS__IPS__ADDR"); // Now it should be 0
......
This diff is collapsed.
......@@ -2986,6 +2986,26 @@ assign RXCDRLOCK = rxcdrlock;
assign RXDLYSRESETDONE = rxdlysresetdone;
assign RXPHALIGNDONE = rxphaligndone;
localparam DRP_LATENCY = 5;
integer drp_latency_counter;
reg drp_rdy_r;
reg [15:0] drp_ram[0:511];
reg [ 8:0] drp_raddr;
assign DRPDO = drp_rdy_r ? drp_ram[drp_raddr] : 16'bz;
assign DRPRDY = drp_rdy_r;
always @ (posedge DRPCLK) begin
if (DRPEN) drp_latency_counter <= DRP_LATENCY;
else if (drp_latency_counter != 0) drp_latency_counter <= drp_latency_counter - 1;
if (DRPEN && DRPWE) drp_ram[DRPADDR] <= DRPDI;
drp_rdy_r <= (drp_latency_counter == 1);
if (DRPEN) drp_raddr <= DRPADDR;
end
initial
forever @ (posedge reset)
begin
......
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