aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/s7_icap_wb.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/s7_icap_wb.v')
-rw-r--r--fpga/usrp3/lib/control/s7_icap_wb.v144
1 files changed, 144 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/s7_icap_wb.v b/fpga/usrp3/lib/control/s7_icap_wb.v
new file mode 100644
index 000000000..114d370eb
--- /dev/null
+++ b/fpga/usrp3/lib/control/s7_icap_wb.v
@@ -0,0 +1,144 @@
+//
+// Copyright 2011-2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// This program 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.
+//
+// This program 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/>.
+//
+
+//
+// Refer to SelectMAP and ICAP docs in UG470
+//
+
+module s7_icap_wb
+ (
+ input clk,
+ input reset,
+ input cyc_i,
+ input stb_i,
+ input we_i,
+ output ack_o,
+ input [31:0] dat_i,
+ output [31:0] dat_o
+ );
+
+ reg rdwrb, csib;
+
+
+ reg [2:0] icap_state;
+ localparam ICAP_IDLE = 0;
+ localparam ICAP_WR0 = 1;
+ localparam ICAP_WR1 = 2;
+ localparam ICAP_RD0 = 3;
+ localparam ICAP_RD1 = 4;
+
+ localparam IDLE = 1'b1;
+ localparam ACTIVE = 1'b0;
+ localparam READ = 1'b1;
+ localparam WRITE = 1'b0;
+
+
+ always @(posedge clk)
+ if(reset) begin
+ rdwrb <= READ;
+ csib <= IDLE;
+ icap_state <= ICAP_IDLE;
+ end
+ else
+ case(icap_state)
+ //
+ // In IDLE state waiting for a READ or WRITE to be signalled from the WB bus.
+ // (In this state rdwrb can flip state without effect because ICAP is not selected)
+ //
+ ICAP_IDLE :
+ begin
+ if(stb_i & cyc_i) begin
+ if(we_i) begin
+ // Start WRITE, assert RDWR_B LOW whilst CSI_B remains HIGH.
+ rdwrb <= WRITE;
+ csib <= IDLE;
+ icap_state <= ICAP_WR0;
+ end else begin
+ // Start READ
+ rdwrb <= READ;
+ csib <= IDLE;
+ icap_state <= ICAP_RD0;
+ end
+ end else begin
+ // Stay IDLE
+ rdwrb <= READ;
+ csib <= IDLE;
+ icap_state <= ICAP_IDLE;
+ end
+ end // case: ICAP_IDLE
+ //
+ // First cycle of WRITE.
+ // Next cycle assert RDWR_B LOW and assert CSI_B LOW.
+ //
+ ICAP_WR0 : begin
+ rdwrb <= WRITE;
+ csib <= ACTIVE;
+ icap_state <= ICAP_WR1;
+ end
+ //
+ // Second cycle of WRITE.
+ // Next cycle assert RDWR_B LOW and assert CSI_B HIGH whilst transitioning to IDLE state
+ //
+ ICAP_WR1 : begin
+ rdwrb <= WRITE;
+ csib <= IDLE;
+ icap_state <= ICAP_IDLE;
+ end
+ //
+ // First cycle of READ.
+ // Next cycle assert RDWR_B HIGH and assert CSI_B LOW.
+ //
+ ICAP_RD0 : begin
+ rdwrb <= READ;
+ csib <= ACTIVE;
+ icap_state <= ICAP_WR1;
+ end
+ //
+ // Second cycle of READ.
+ // Next cycle assert RDWR_B HIGH and assert CSI_B HIGH whilst transitioning to IDLE state
+ //
+ ICAP_RD1 : begin
+ rdwrb <= READ;
+ csib <= IDLE;
+ icap_state <= ICAP_IDLE;
+ end
+
+ endcase // case (icap_state)
+
+ assign ack_o = (icap_state == ICAP_WR1) | (icap_state == ICAP_RD1);
+ //assign debug_out = {17'd0, BUSY, dat_i[7:0], ~CE, ICAPCLK, ~WRITE, icap_state};
+
+
+ ICAPE2 #(
+ .DEVICE_ID(32'h03651093),
+ .ICAP_WIDTH("X32"),
+ .SIM_CFG_FILE_NAME("NONE")
+ )
+ ICAPE2_inst (
+ .O(/*dat_o[31:0]*/),
+ .CLK(clk), // Rising edge referenced for both reads and writes.
+ .CSIB(csib), // CSIB = 0 to select ICAP
+ .I(dat_i[31:0]), // Bitswaped as per SELECTMAP (See UG470 page 40)
+ .RDWRB(rdwrb) // RDWB = 0 for WRITE, = 1 for READ
+ );
+
+ assign dat_0 = 32'h0;
+
+endmodule // s3a_icap_wb