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 @@
<link>
<name>vivado_logs/VivadoBitstream.log</name>
<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>
<name>vivado_logs/VivadoOpt.log</name>
<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>
<name>vivado_logs/VivadoOptPhys.log</name>
<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>
<name>vivado_logs/VivadoOptPower.log</name>
<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>
<name>vivado_logs/VivadoPlace.log</name>
<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>
<name>vivado_logs/VivadoRoute.log</name>
<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>
<name>vivado_logs/VivadoSynthesis.log</name>
<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>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<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>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<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>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<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>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<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>
<name>vivado_state/x393_sata-opt-phys.dcp</name>
<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>
<name>vivado_state/x393_sata-opt-power.dcp</name>
<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>
<name>vivado_state/x393_sata-opt.dcp</name>
<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>
<name>vivado_state/x393_sata-place.dcp</name>
<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>
<name>vivado_state/x393_sata-route.dcp</name>
<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>
<name>vivado_state/x393_sata-synth.dcp</name>
<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>
</linkedResources>
</projectDescription>
This diff is collapsed.
......@@ -144,7 +144,7 @@ module ahci_fsm
input dma_cmd_busy, // output reg (DMA engine is processing PRDs)
/// input dma_cmd_done, // output (last PRD is over)
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)
// Debug features
......@@ -257,15 +257,20 @@ module ahci_fsm
// reg jump_r;
reg [2:0] fsm_jump;
wire fsm_next;
reg fsm_next_r;
// reg fsm_next_r;
reg fsm_actions; // processing actions
reg fsm_act_busy;
reg [1:0] fsm_transitions; // processing transitions
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
// reg [7:0] conditions;
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 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_last_act_w = pgm_data[17];
......@@ -283,6 +288,14 @@ module ahci_fsm
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;
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 update_all = fsm_jump[0];
......@@ -344,8 +357,9 @@ module ahci_fsm
if (fsm_actions && fsm_next) was_last_action_r <= fsm_last_act_w;
if (hba_rst || pre_jump_w) fsm_transitions <= 0;
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 if (fsm_transitions_w) 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]};
if (hba_rst) fsm_preload <= 0;
......@@ -460,6 +474,7 @@ module ahci_fsm
// Condition inputs may be registered if needed
condition_mux condition_mux_i (
.clk (mclk), // input
.ce (conditions_ce), // input
.sel (pgm_data[17:10]), // input[7:0]
.condition (cond_met_w), // output
//COMPOSITE
......
......@@ -92,7 +92,9 @@ module ahci_sata_layers #(
input wire rxp_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
......@@ -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
reg h2d_pending; // HBA started sending FIS to fifo
wire [31:0] debug_phy;
wire [31:0] debug_link;
// wire [31:0] debug_phy;
// wire [31:0] debug_link;
wire rxelsfull;
wire rxelsempty;
......@@ -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: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 d2h_valid = d2h_nempty;
......@@ -260,7 +262,7 @@ module ahci_sata_layers #(
.link_reset (ll_link_reset), // input wire // oob sequence is reinitiated and link now is not established or rxelecidle
.sync_escape_req (syncesc_send), // input wire // TL demands to brutally cancel current transaction
.sync_escape_ack (syncesc_send_done), // output wire // acknowlegement of a successful reception?
.incom_stop_req (pcmd_st_cleared), // input wire // TL demands to stop current recieving session
.incom_stop_req (pcmd_st_cleared), // input wire // TL demands to stop current recieving session
.link_established (link_established),
// inputs from phy
.phy_ready (phy_ready), // input wire // phy is ready - link is established
......
This diff is collapsed.
......@@ -115,7 +115,10 @@ module axi_ahci_regs#(
output afi_cache_set,
output was_hba_rst, // last reset was hba reset (not counting system 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
// Datascope interface (write to memory that can be software-read)
,input datascope_clk,
......@@ -188,6 +191,7 @@ module axi_ahci_regs#(
reg wait_first_access = RESET_TO_FIRST_ACCESS; // keep port reset until first access
wire any_access = bram_wen_r || bram_ren[0];
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]);
......@@ -198,7 +202,6 @@ 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
if (arst) write_busy_r <= 0;
......@@ -207,7 +210,7 @@ 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;
// if (bram_ren[1]) bram_rdata_r <= debug_rd_r? debug_in : bram_rdata;
bram_wstb_r <= {4{bram_wen}} & bram_wstb;
......@@ -215,8 +218,17 @@ module axi_ahci_regs#(
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
//debug_rd_r
generate
genvar i;
for (i=0; i < 32; i=i+1) begin: bit_type_block
......@@ -281,10 +293,6 @@ module axi_ahci_regs#(
if (pgm_fsm_set_w) pgm_ad <= ahci_regs_di[17:0];
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 @@
reg [2:0] nhrst_r;
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
if (arst) nhrst_r <= 0;
......@@ -365,7 +366,8 @@
.sctl_ipm (sctl_ipm), // output[3:0]
.sctl_spd (sctl_spd), // output[3:0]
.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 #(
......@@ -424,7 +426,8 @@
.txn_out (TXN), // output wire
.rxp_in (RXP), // 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
* Date:2016-01-27
* Date:2016-02-07
* Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Decode sequencer code to 1-hot actions
*******************************************************************************/
......
/*******************************************************************************
* Module: condition_mux
* Date:2016-01-27
* Date:2016-02-07
* Author: auto-generated file, see ahci_fsm_sequence.py
* Description: Select condition
*******************************************************************************/
......@@ -9,6 +9,7 @@
module condition_mux (
input clk,
input ce, // enable recording all conditions
input [ 7:0] sel,
output condition,
input ST_NB_ND,
......@@ -57,57 +58,104 @@ module condition_mux (
input X_RDY_COLLISION);
wire [44:0] masked;
reg [43:0] registered;
reg [ 5:0] cond_r;
assign condition = |cond_r;
assign masked[ 0] = ST_NB_ND && sel[ 2] && sel[ 1] && sel[ 0];
assign masked[ 1] = PXCI0_NOT_CMDTOISSUE && sel[ 3] && sel[ 1] && sel[ 0];
assign masked[ 2] = PCTI_CTBAR_XCZ && sel[ 4] && sel[ 1] && sel[ 0];
assign masked[ 3] = PCTI_XCZ && sel[ 5] && sel[ 1] && sel[ 0];
assign masked[ 4] = NST_D2HR && sel[ 6] && sel[ 1] && sel[ 0];
assign masked[ 5] = NPD_NCA && sel[ 7] && sel[ 1] && sel[ 0];
assign masked[ 6] = CHW_DMAA && sel[ 3] && sel[ 2] && sel[ 0];
assign masked[ 7] = SCTL_DET_CHANGED_TO_4 && sel[ 4] && sel[ 2] && sel[ 0];
assign masked[ 8] = SCTL_DET_CHANGED_TO_1 && sel[ 5] && sel[ 2] && sel[ 0];
assign masked[ 9] = PXSSTS_DET_NE_3 && sel[ 6] && sel[ 2] && sel[ 0];
assign masked[10] = PXSSTS_DET_EQ_1 && sel[ 7] && sel[ 2] && sel[ 0];
assign masked[11] = NPCMD_FRE && sel[ 4] && sel[ 3] && sel[ 0];
assign masked[12] = FIS_OK && sel[ 5] && sel[ 3] && sel[ 0];
assign masked[13] = FIS_ERR && sel[ 6] && sel[ 3] && sel[ 0];
assign masked[14] = FIS_FERR && sel[ 7] && sel[ 3] && sel[ 0];
assign masked[15] = FIS_EXTRA && sel[ 5] && sel[ 4] && sel[ 0];
assign masked[16] = FIS_FIRST_INVALID && sel[ 6] && sel[ 4] && sel[ 0];
assign masked[17] = FR_D2HR && sel[ 7] && sel[ 4] && sel[ 0];
assign masked[18] = FIS_DATA && sel[ 6] && sel[ 5] && sel[ 0];
assign masked[19] = FIS_ANY && sel[ 7] && sel[ 5] && sel[ 0];
assign masked[20] = NB_ND_D2HR_PIO && sel[ 7] && sel[ 6] && sel[ 0];
assign masked[21] = D2HR && sel[ 3] && sel[ 2] && sel[ 1];
assign masked[22] = SDB && sel[ 4] && sel[ 2] && sel[ 1];
assign masked[23] = DMA_ACT && sel[ 5] && sel[ 2] && sel[ 1];
assign masked[24] = DMA_SETUP && sel[ 6] && sel[ 2] && sel[ 1];
assign masked[25] = BIST_ACT_FE && sel[ 7] && sel[ 2] && sel[ 1];
assign masked[26] = BIST_ACT && sel[ 4] && sel[ 3] && sel[ 1];
assign masked[27] = PIO_SETUP && sel[ 5] && sel[ 3] && sel[ 1];
assign masked[28] = NB_ND && sel[ 6] && sel[ 3] && sel[ 1];
assign masked[29] = TFD_STS_ERR && sel[ 7] && sel[ 3] && sel[ 1];
assign masked[30] = FIS_I && sel[ 5] && sel[ 4] && sel[ 1];
assign masked[31] = PIO_I && sel[ 6] && sel[ 4] && sel[ 1];
assign masked[32] = NPD && sel[ 7] && sel[ 4] && sel[ 1];
assign masked[33] = PIOX && sel[ 6] && sel[ 5] && sel[ 1];
assign masked[34] = XFER0 && sel[ 7] && sel[ 5] && sel[ 1];
assign masked[35] = PIOX_XFER0 && sel[ 7] && sel[ 6] && sel[ 1];
assign masked[36] = CTBAA_CTBAP && sel[ 4] && sel[ 3] && sel[ 2];
assign masked[37] = CTBAP && sel[ 5] && sel[ 3] && sel[ 2];
assign masked[38] = CTBA_B && sel[ 6] && sel[ 3] && sel[ 2];
assign masked[39] = CTBA_C && sel[ 7] && sel[ 3] && sel[ 2];
assign masked[40] = TX_ERR && sel[ 5] && sel[ 4] && sel[ 2];
assign masked[41] = SYNCESC_ERR && sel[ 6] && sel[ 4] && sel[ 2];
assign masked[42] = DMA_PRD_IRQ_PEND && sel[ 7] && sel[ 4] && sel[ 2];
assign masked[43] = X_RDY_COLLISION && sel[ 6] && sel[ 5] && sel[ 2];
assign masked[ 0] = registered[ 0] && sel[ 2] && sel[ 1] && sel[ 0];
assign masked[ 1] = registered[ 1] && sel[ 3] && sel[ 1] && sel[ 0];
assign masked[ 2] = registered[ 2] && sel[ 4] && sel[ 1] && sel[ 0];
assign masked[ 3] = registered[ 3] && sel[ 5] && sel[ 1] && sel[ 0];
assign masked[ 4] = registered[ 4] && sel[ 6] && sel[ 1] && sel[ 0];
assign masked[ 5] = registered[ 5] && sel[ 7] && sel[ 1] && sel[ 0];
assign masked[ 6] = registered[ 6] && sel[ 3] && sel[ 2] && sel[ 0];
assign masked[ 7] = registered[ 7] && sel[ 4] && sel[ 2] && sel[ 0];
assign masked[ 8] = registered[ 8] && sel[ 5] && sel[ 2] && sel[ 0];
assign masked[ 9] = registered[ 9] && sel[ 6] && sel[ 2] && sel[ 0];
assign masked[10] = registered[10] && sel[ 7] && sel[ 2] && sel[ 0];
assign masked[11] = registered[11] && sel[ 4] && sel[ 3] && sel[ 0];
assign masked[12] = registered[12] && sel[ 5] && sel[ 3] && sel[ 0];
assign masked[13] = registered[13] && sel[ 6] && sel[ 3] && sel[ 0];
assign masked[14] = registered[14] && sel[ 7] && sel[ 3] && sel[ 0];
assign masked[15] = registered[15] && sel[ 5] && sel[ 4] && sel[ 0];
assign masked[16] = registered[16] && sel[ 6] && sel[ 4] && sel[ 0];
assign masked[17] = registered[17] && sel[ 7] && sel[ 4] && sel[ 0];
assign masked[18] = registered[18] && sel[ 6] && sel[ 5] && sel[ 0];
assign masked[19] = registered[19] && sel[ 7] && sel[ 5] && sel[ 0];
assign masked[20] = registered[20] && sel[ 7] && sel[ 6] && sel[ 0];
assign masked[21] = registered[21] && sel[ 3] && sel[ 2] && sel[ 1];
assign masked[22] = registered[22] && sel[ 4] && sel[ 2] && sel[ 1];
assign masked[23] = registered[23] && sel[ 5] && sel[ 2] && sel[ 1];
assign masked[24] = registered[24] && sel[ 6] && sel[ 2] && sel[ 1];
assign masked[25] = registered[25] && sel[ 7] && sel[ 2] && sel[ 1];
assign masked[26] = registered[26] && sel[ 4] && sel[ 3] && sel[ 1];
assign masked[27] = registered[27] && sel[ 5] && sel[ 3] && sel[ 1];
assign masked[28] = registered[28] && sel[ 6] && sel[ 3] && sel[ 1];
assign masked[29] = registered[29] && sel[ 7] && sel[ 3] && sel[ 1];
assign masked[30] = registered[30] && sel[ 5] && sel[ 4] && sel[ 1];
assign masked[31] = registered[31] && sel[ 6] && sel[ 4] && sel[ 1];
assign masked[32] = registered[32] && sel[ 7] && sel[ 4] && sel[ 1];
assign masked[33] = registered[33] && sel[ 6] && sel[ 5] && sel[ 1];
assign masked[34] = registered[34] && sel[ 7] && sel[ 5] && sel[ 1];
assign masked[35] = registered[35] && sel[ 7] && sel[ 6] && sel[ 1];
assign masked[36] = registered[36] && sel[ 4] && sel[ 3] && sel[ 2];
assign masked[37] = registered[37] && sel[ 5] && sel[ 3] && sel[ 2];
assign masked[38] = registered[38] && sel[ 6] && sel[ 3] && sel[ 2];
assign masked[39] = registered[39] && sel[ 7] && sel[ 3] && sel[ 2];
assign masked[40] = registered[40] && sel[ 5] && sel[ 4] && sel[ 2];
assign masked[41] = registered[41] && sel[ 6] && sel[ 4] && sel[ 2];
assign masked[42] = registered[42] && sel[ 7] && sel[ 4] && sel[ 2];
assign masked[43] = registered[43] && sel[ 6] && sel[ 5] && sel[ 2];
assign masked[44] = !(|sel); // always TRUE condition (sel ==0)
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[ 1] <= |masked[15: 8];
cond_r[ 2] <= |masked[23:16];
......
......@@ -53,7 +53,7 @@ actions = ['NOP',
# FIS_TRANSMIT
'CLEAR_CMD_TO_ISSUE',
# DMA
'DMA_ABORT', 'DMA_PRD_IRQ_CLEAR',
'DMA_ABORT*', 'DMA_PRD_IRQ_CLEAR',
# SATA TRANSPORT/LINK/PHY
'XMIT_COMRESET', 'SEND_SYNC_ESC*', 'SET_OFFLINE', 'R_OK', 'R_ERR',
# FIS TRANSMIT/WAIT DONE
......@@ -158,7 +158,7 @@ sequence = [{LBL:'POR', ADDR: 0x0, ACT: NOP},
{ GOTO:'P:NotRunning'},
{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: 'XFER_CNTR_CLEAR'}, # clear_xfer_cntr
......@@ -477,6 +477,7 @@ def condition_mux_verilog(conditions, condition_vals, module_name, fanout, file=
module %s (
input clk,
input ce, // enable recording all conditions
input [%2d:0] sel,
output condition,"""
v=max(condition_vals.values())
......@@ -485,15 +486,14 @@ module %s (
num_inputs += 1
v >>= 1
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)
header = header_template%(module_name, datetime.date.today().isoformat(), os.path.basename(__file__), module_name, num_inputs-1)
print(header,file=file)
for input_name in conditions[:len(conditions)-1]:
print(" input %s,"%(input_name),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(" input %s,"%(input_name), file=file)
print(" input %s);\n"%(conditions[-1]), file=file)
print(" wire [%2d:0] masked;"%(len(conditions)), file=file)
print(" reg [%2d:0] registered;"%(len(conditions) -1),file=file)
if numregs > 1:
print(" reg [%2d:0] cond_r;\n"%(numregs-1),file=file)
else:
......@@ -505,7 +505,8 @@ module %s (
print(" assign condition = cond_r;\n",file=file)
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]]
for nb in range(num_inputs-1,-1,-1):
......@@ -514,7 +515,13 @@ module %s (
print (";", 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)