1// 2// Copyright 2011-2012 Ettus Research LLC 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU General Public License for more details. 13// 14// You should have received a copy of the GNU General Public License 15// along with this program. If not, see <http://www.gnu.org/licenses/>. 16// 17 18////////////////////////////////////////////////////////////////////////////////// 19 20//this is a FIFO master interface for the FX2 in "slave fifo" mode. 21 22module slave_fifo 23 #( 24 //how many cycles max in a transfer state 25 parameter DATA_XFER_COUNT = 256, 26 parameter CTRL_XFER_COUNT = 32, 27 28 //sizes for fifo36 2 clock cascade fifos 29 parameter DATA_RX_FIFO_SIZE = 9, 30 parameter DATA_TX_FIFO_SIZE = 9, 31 parameter CTRL_RX_FIFO_SIZE = 9, 32 parameter CTRL_TX_FIFO_SIZE = 9 33 ) 34 (// GPIF signals 35 input gpif_clk, input gpif_rst, 36 inout [15:0] gpif_d, 37 input [3:0] gpif_ctl, 38 output reg sloe, output reg slrd, output reg slwr, output reg pktend, output reg [1:0] fifoadr, 39 40 // FIFO interface 41 input fifo_clk, input fifo_rst, 42 output [35:0] tx_data, output tx_src_rdy, input tx_dst_rdy, 43 input [35:0] rx_data, input rx_src_rdy, output rx_dst_rdy, 44 output [35:0] ctrl_data, output ctrl_src_rdy, input ctrl_dst_rdy, 45 input [35:0] resp_data, input resp_src_rdy, output resp_dst_rdy, 46 47 output [31:0] debug 48 ); 49 50 wire FX2_DE_pre = ~gpif_ctl[0]; //EP2 FX2 FIFO empty (FLAGA) 51 wire FX2_CE_pre = ~gpif_ctl[1]; //EP4 FX2 FIFO empty (FLAGB) 52 wire FX2_DF_pre = ~gpif_ctl[2]; //EP6 FX2 FIFO full (FLAGC) 53 wire FX2_CF_pre = ~gpif_ctl[3]; //EP8 FX2 FIFO full (FLAGD) 54 55 reg FX2_DE, FX2_CE, FX2_DF, FX2_CF; 56 always @(posedge gpif_clk) begin 57 FX2_DE <= FX2_DE_pre; //EP2 FX2 FIFO empty (FLAGA) 58 FX2_CE <= FX2_CE_pre; //EP4 FX2 FIFO empty (FLAGB) 59 FX2_DF <= FX2_DF_pre; //EP6 FX2 FIFO full (FLAGC) 60 FX2_CF <= FX2_CF_pre; //EP8 FX2 FIFO full (FLAGD) 61 end 62 63 wire [15:0] gpif_d_out_ctrl, gpif_d_out_data; 64 reg [15:0] gpif_d_out, gpif_d_in; 65 66 // //////////////////////////////////////////////////////////////////// 67 // GPIF bus master state machine 68 69 wire rx_valid, resp_valid; 70 reg tx_valid, ctrl_valid; 71 wire tx_ready, ctrl_ready; 72 reg rx_enable, resp_enable; 73 wire rx_data_enough_occ; 74 75 reg [9:0] transfer_count; //number of lines (a line is 16 bits) in active transfer 76 77 reg [3:0] state; //state machine current state 78 localparam STATE_IDLE = 0; 79 localparam STATE_THINK = 1; 80 localparam STATE_DATA_RX = 2; 81 localparam STATE_DATA_TX = 3; 82 localparam STATE_CTRL_RX = 4; 83 localparam STATE_CTRL_TX = 5; 84 localparam STATE_DATA_TX_SLOE = 6; 85 localparam STATE_CTRL_TX_SLOE = 7; 86 localparam STATE_DATA_RX_ADR = 8; 87 localparam STATE_CTRL_RX_ADR = 9; 88 89 //logs the last bus user for xfer fairness 90 //we only care about data rx vs. tx since ctrl pkts are so short 91 reg last_data_bus_hog; 92 localparam BUS_HOG_RX = 0; 93 localparam BUS_HOG_TX = 1; 94 95 wire resp_eof; 96 reg [1:0] idle_count; 97 98 // ////////////////////////////////////////////////////////////// 99 // FX2 slave FIFO bus master state machine 100 // 101 always @(posedge gpif_clk) 102 if(gpif_rst) begin 103 state <= STATE_IDLE; 104 sloe <= 1; 105 slrd <= 1; 106 slwr <= 1; 107 pktend <= 1; 108 rx_enable <= 0; 109 tx_valid <= 0; 110 ctrl_valid <= 0; 111 resp_enable <= 0; 112 idle_count <= 0; 113 end 114 else case (state) 115 STATE_IDLE: begin 116 transfer_count <= 0; 117 sloe <= 1; 118 slrd <= 1; 119 slwr <= 1; 120 pktend <= 1; 121 rx_enable <= 0; 122 tx_valid <= 0; 123 ctrl_valid <= 0; 124 resp_enable <= 0; 125 if (idle_count == 2'b11) state <= STATE_THINK; 126 idle_count <= idle_count + 1; 127 end 128 129 STATE_THINK: begin 130 131 idle_count <= 0; 132 133 //handle transitions to other states 134 if(ctrl_ready & ~FX2_CE) begin //if there's room in the ctrl fifo and the FX2 has ctrl data 135 state <= STATE_CTRL_TX_SLOE; 136 fifoadr <= 2'b01; 137 sloe <= 0; 138 end 139 else if(resp_valid & ~FX2_CF) begin //if the ctrl fifo has data and the FX2 isn't full 140 state <= STATE_CTRL_RX_ADR; 141 fifoadr <= 2'b11; 142 end 143 else if(tx_ready & ~FX2_DE & last_data_bus_hog == BUS_HOG_RX) begin //if there's room in the data fifo and the FX2 has data 144 state <= STATE_DATA_TX_SLOE; 145 last_data_bus_hog <= BUS_HOG_TX; 146 fifoadr <= 2'b00; 147 sloe <= 0; 148 end 149 else if(rx_data_enough_occ & ~FX2_DF & last_data_bus_hog == BUS_HOG_TX) begin //if the data fifo has data and the FX2 isn't full 150 state <= STATE_DATA_RX_ADR; 151 last_data_bus_hog <= BUS_HOG_RX; 152 fifoadr <= 2'b10; 153 end 154 else if(tx_ready & ~FX2_DE) begin 155 state <= STATE_DATA_TX_SLOE; 156 last_data_bus_hog <= BUS_HOG_TX; 157 fifoadr <= 2'b00; 158 sloe <= 0; 159 end 160 else if(rx_data_enough_occ & ~FX2_DF) begin 161 state <= STATE_DATA_RX_ADR; 162 last_data_bus_hog <= BUS_HOG_RX; 163 fifoadr <= 2'b10; 164 end 165 end 166 167 STATE_DATA_TX_SLOE: begin //just to assert SLOE one cycle before SLRD 168 state <= STATE_DATA_TX; 169 slrd <= 0; 170 end 171 172 STATE_CTRL_TX_SLOE: begin 173 state <= STATE_CTRL_TX; 174 slrd <= 0; 175 end 176 177 STATE_DATA_RX_ADR: begin //just to assert FIFOADR one cycle before SLWR 178 state <= STATE_DATA_RX; 179 rx_enable <= 1; 180 end 181 182 STATE_CTRL_RX_ADR: begin 183 state <= STATE_CTRL_RX; 184 resp_enable <= 1; 185 end 186 187 STATE_DATA_RX: begin 188 if (FX2_DF_pre || ~rx_valid || transfer_count == DATA_XFER_COUNT-1) begin 189 state <= STATE_IDLE; 190 rx_enable <= 0; 191 end 192 gpif_d_out <= gpif_d_out_data; 193 slwr <= ~rx_valid; 194 transfer_count <= transfer_count + 1; 195 end 196 197 STATE_DATA_TX: begin 198 if (FX2_DE_pre || transfer_count == DATA_XFER_COUNT-1) begin 199 state <= STATE_IDLE; 200 slrd <= 1; 201 end 202 gpif_d_in <= gpif_d; 203 tx_valid <= 1; 204 transfer_count <= transfer_count + 1; 205 end 206 207 STATE_CTRL_RX: begin 208 if (FX2_CF_pre || ~resp_valid || resp_eof || transfer_count == CTRL_XFER_COUNT-1) begin 209 state <= STATE_IDLE; 210 resp_enable <= 0; 211 end 212 pktend <= ~resp_eof; 213 gpif_d_out <= gpif_d_out_ctrl; 214 slwr <= ~resp_valid; 215 transfer_count <= transfer_count + 1; 216 end 217 218 STATE_CTRL_TX: begin 219 if (FX2_CE_pre || transfer_count == CTRL_XFER_COUNT-1) begin 220 state <= STATE_IDLE; 221 slrd <= 1; 222 end 223 gpif_d_in <= gpif_d; 224 ctrl_valid <= 1; 225 transfer_count <= transfer_count + 1; 226 end 227 endcase 228 229 // GPIF output data lines, tristate 230 assign gpif_d = (sloe)? gpif_d_out[15:0] : 16'bz; 231 232 // //////////////////////////////////////////////////////////////////// 233 // TX Data Path 234 235 gpmc16_to_fifo36 #(.FIFO_SIZE(DATA_TX_FIFO_SIZE), .MIN_SPACE16(DATA_XFER_COUNT)) fifo36_to_gpmc16_tx( 236 .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), 237 .in_data(gpif_d_in), .ready(tx_ready), .valid(tx_valid), 238 .fifo_clk(fifo_clk), .fifo_rst(fifo_rst), 239 .out_data(tx_data), .out_src_rdy(tx_src_rdy), .out_dst_rdy(tx_dst_rdy) 240 ); 241 242 // //////////////////////////////////////////// 243 // RX Data Path 244 245 fifo36_to_gpmc16 #(.FIFO_SIZE(DATA_RX_FIFO_SIZE), .MIN_OCC16(DATA_XFER_COUNT)) fifo36_to_gpmc16_rx( 246 .fifo_clk(fifo_clk), .fifo_rst(fifo_rst), 247 .in_data(rx_data), .in_src_rdy(rx_src_rdy), .in_dst_rdy(rx_dst_rdy), 248 .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), 249 .has_data(rx_data_enough_occ), 250 .out_data(gpif_d_out_data), .valid(rx_valid), .enable(rx_enable) 251 ); 252 253 // //////////////////////////////////////////////////////////////////// 254 // CTRL TX Data Path 255 256 gpmc16_to_fifo36 #(.FIFO_SIZE(CTRL_TX_FIFO_SIZE), .MIN_SPACE16(CTRL_XFER_COUNT)) fifo36_to_gpmc16_ctrl( 257 .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), 258 .in_data(gpif_d_in), .ready(ctrl_ready), .valid(ctrl_valid), 259 .fifo_clk(fifo_clk), .fifo_rst(fifo_rst), 260 .out_data(ctrl_data), .out_src_rdy(ctrl_src_rdy), .out_dst_rdy(ctrl_dst_rdy) 261 ); 262 263 // //////////////////////////////////////////// 264 // CTRL RX Data Path 265 266 fifo36_to_gpmc16 #(.FIFO_SIZE(CTRL_RX_FIFO_SIZE)) fifo36_to_gpmc16_resp( 267 .fifo_clk(fifo_clk), .fifo_rst(fifo_rst), 268 .in_data(resp_data), .in_src_rdy(resp_src_rdy), .in_dst_rdy(resp_dst_rdy), 269 .gpif_clk(gpif_clk), .gpif_rst(gpif_rst), 270 .out_data(gpif_d_out_ctrl), .valid(resp_valid), .enable(resp_enable), 271 .eof(resp_eof) 272 ); 273 274 assign debug = 0; 275 276endmodule // slave_fifo 277