rtl/verilog/master_ctrl.v

Sat, 06 Aug 2011 01:48:48 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:48:48 +0100
changeset 1
522426d22baa
parent 0
11aef665a5d8
permissions
-rw-r--r--

Update to LM32 DMA v3.3

+// Version : 3.2
+// : 1. Support for 8/32-bit WISHBONE Data Bus. The Control and
+// : Read/Write Ports can be independently configured.
+// : 2. Support for "retry" on receipt of a WISHBONE RTY. This
+// : retry results in the current burst or classic cycle
+// : being issued again after a retry timeout.
+// : 3. Support for "error" on receipt of a WISHBONE ERR. This
+// : results in the current dma transfer being terminated
+// : and the error is updated within the STATUS CSR.
+// : 4. Support for burst size of 64.
+// :
+// Version : 3.3
+// : Support for MachXO2 added. The MachXO2 only has a FIFO
+// : with separate read/write clocks.

philpem@1 1 // ==================================================================
philpem@1 2 // >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
philpem@1 3 // ------------------------------------------------------------------
philpem@1 4 // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
philpem@1 5 // ALL RIGHTS RESERVED
philpem@1 6 // ------------------------------------------------------------------
philpem@1 7 //
philpem@1 8 // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
philpem@1 9 //
philpem@1 10 // Permission:
philpem@1 11 //
philpem@1 12 // Lattice Semiconductor grants permission to use this code
philpem@1 13 // pursuant to the terms of the Lattice Semiconductor Corporation
philpem@1 14 // Open Source License Agreement.
philpem@1 15 //
philpem@1 16 // Disclaimer:
philpem@0 17 //
philpem@1 18 // Lattice Semiconductor provides no warranty regarding the use or
philpem@1 19 // functionality of this code. It is the user's responsibility to
philpem@1 20 // verify the user’s design for consistency and functionality through
philpem@1 21 // the use of formal verification methods.
philpem@1 22 //
philpem@1 23 // --------------------------------------------------------------------
philpem@1 24 //
philpem@1 25 // Lattice Semiconductor Corporation
philpem@1 26 // 5555 NE Moore Court
philpem@1 27 // Hillsboro, OR 97214
philpem@1 28 // U.S.A
philpem@1 29 //
philpem@1 30 // TEL: 1-800-Lattice (USA and Canada)
philpem@1 31 // 503-286-8001 (other locations)
philpem@1 32 //
philpem@1 33 // web: http://www.latticesemi.com/
philpem@1 34 // email: techsupport@latticesemi.com
philpem@1 35 //
philpem@1 36 // --------------------------------------------------------------------
philpem@0 37 // FILE DETAILS
philpem@0 38 // Project : LM32 DMA Component
philpem@1 39 // File : wb_dma_ctrl.v
philpem@1 40 // Title : DMA controller top file
philpem@0 41 // Dependencies : None
philpem@1 42 // :
philpem@1 43 // Version : 7.0
philpem@1 44 // : Initial Release
philpem@1 45 // :
philpem@1 46 // Version : 7.0SP2, 3.0
philpem@1 47 // : 1. Read and Write channel of DMA controller are working in
philpem@1 48 // : parallel, due to that now as soon as FIFO is not empty
philpem@1 49 // : write channel of the DMA controller start writing data
philpem@1 50 // : to the slave.
philpem@1 51 // : 2. Burst Size supported by DMA controller is increased to
philpem@1 52 // : support bigger burst (from current value of 4 and 8 to
philpem@1 53 // : 16 and 32). Now 4 different type of burst sizes are
philpem@1 54 // : supported by the DMA controller 4, 8, 16 and 32. For
philpem@1 55 // : this Burst Size field of the control register is
philpem@1 56 // : increased to 2 bits.
philpem@1 57 // : 3. Glitch is removed on the S_ACK_O signal.
philpem@1 58 // :
philpem@1 59 // Version : 3.1
philpem@1 60 // : Make DMA Engine compliant to Rule 3.100 of Wishbone Spec
philpem@1 61 // : which defines alignement of bytes in sub-word transfers.
philpem@1 62 // :
philpem@1 63 // Version : 3.2
philpem@1 64 // : 1. Support for 8/32-bit WISHBONE Data Bus. The Control and
philpem@1 65 // : Read/Write Ports can be independently configured.
philpem@1 66 // : 2. Support for "retry" on receipt of a WISHBONE RTY. This
philpem@1 67 // : retry results in the current burst or classic cycle
philpem@1 68 // : being issued again after a retry timeout.
philpem@1 69 // : 3. Support for "error" on receipt of a WISHBONE ERR. This
philpem@1 70 // : results in the current dma transfer being terminated
philpem@1 71 // : and the error is updated within the STATUS CSR.
philpem@1 72 // : 4. Support for burst size of 64.
philpem@1 73 // :
philpem@1 74 // Version : 3.3
philpem@1 75 // : Support for MachXO2 added. The MachXO2 only has a FIFO
philpem@1 76 // : with separate read/write clocks.
philpem@0 77 // =============================================================================
philpem@0 78
philpem@0 79 `ifndef MASTER_CTRL_FILE
philpem@0 80 `define MASTER_CTRL_FILE
philpem@0 81 `include "system_conf.v"
philpem@0 82 module MASTER_CTRL
philpem@1 83 #(parameter MA_WB_DAT_WIDTH = 32,
philpem@1 84 parameter MA_WB_ADR_WIDTH = 32,
philpem@1 85 parameter MB_WB_DAT_WIDTH = 32,
philpem@1 86 parameter MB_WB_ADR_WIDTH = 32,
philpem@1 87 parameter S_WB_DAT_WIDTH = 32,
philpem@0 88 parameter FIFO_IMPLEMENTATION = "EBR")
philpem@1 89 (
philpem@1 90 // System clock and reset
philpem@1 91 input CLK_I,
philpem@1 92 input RST_I,
philpem@1 93 // Master read port
philpem@1 94 output reg [MA_WB_ADR_WIDTH-1:0] MA_ADR_O,
philpem@1 95 output reg [MA_WB_DAT_WIDTH/8-1:0] MA_SEL_O,
philpem@1 96 output reg [MA_WB_DAT_WIDTH-1:0] MA_DAT_O,
philpem@1 97 output reg MA_WE_O,
philpem@1 98 output reg MA_STB_O,
philpem@1 99 output reg MA_CYC_O,
philpem@1 100 output reg [2:0] MA_CTI_O,
philpem@1 101 output reg MA_LOCK_O,
philpem@1 102 input [MA_WB_DAT_WIDTH-1:0] MA_DAT_I,
philpem@1 103 input MA_ACK_I,
philpem@1 104 input MA_ERR_I,
philpem@1 105 input MA_RTY_I,
philpem@1 106 // Master write port
philpem@1 107 output reg [MB_WB_ADR_WIDTH-1:0] MB_ADR_O,
philpem@1 108 output reg [MB_WB_DAT_WIDTH/8-1:0] MB_SEL_O,
philpem@1 109 output reg [MB_WB_DAT_WIDTH-1:0] MB_DAT_O,
philpem@1 110 output reg MB_WE_O,
philpem@1 111 output reg MB_STB_O,
philpem@1 112 output reg MB_CYC_O,
philpem@1 113 output reg [2:0] MB_CTI_O,
philpem@1 114 output reg MB_LOCK_O,
philpem@1 115 input MB_ACK_I,
philpem@1 116 input MB_ERR_I,
philpem@1 117 input MB_RTY_I,
philpem@1 118 // Register interface
philpem@1 119 input reg_start,
philpem@1 120 output reg reg_busy,
philpem@1 121 output reg reg_status,
philpem@1 122 output reg reg_interrupt,
philpem@1 123 input reg_bt3, reg_bt2, reg_bt1, reg_bt0,
philpem@1 124 input reg_s_con, reg_d_con,
philpem@1 125 input reg_incw, reg_inchw,
philpem@1 126 input [7:0] reg_rdelay,
philpem@1 127 input [31:0] reg_00_data,
philpem@1 128 input [31:0] reg_04_data,
philpem@1 129 input [31:0] reg_08_data
philpem@1 130 );
philpem@1 131
philpem@1 132 parameter lat_family = `LATTICE_FAMILY;
philpem@1 133 parameter UDLY = 1;
philpem@1 134
philpem@1 135 wire [MB_WB_DAT_WIDTH-1:0] fifo_dout;
philpem@1 136 wire fifo_empty, fifo_aempty;
philpem@1 137 reg [MA_WB_DAT_WIDTH-1:0] fifo_din;
philpem@1 138
philpem@1 139 reg [31:0] xfer_length, xfer_length_nxt;
philpem@1 140 reg [5:0] rburst_count, rburst_count_nxt;
philpem@1 141 reg [5:0] wburst_count, wburst_count_nxt;
philpem@1 142 reg [5:0] save_wburst_count, save_wburst_count_nxt;
philpem@1 143 reg [31:0] raddr_checkpoint, raddr_checkpoint_nxt, waddr_checkpoint, waddr_checkpoint_nxt;
philpem@1 144 reg [7:0] retry_delay, retry_delay_nxt;
philpem@1 145 reg MA_CYC_O_nxt, MA_STB_O_nxt, MA_CYC_O_d;
philpem@1 146 reg [2:0] MA_CTI_O_nxt;
philpem@1 147 reg [MA_WB_ADR_WIDTH-1:0] MA_ADR_O_nxt;
philpem@1 148 reg [MA_WB_DAT_WIDTH/8-1:0] MA_SEL_O_nxt;
philpem@1 149 reg MB_CYC_O_nxt, MB_STB_O_nxt, MB_CYC_O_d;
philpem@1 150 reg [2:0] MB_CTI_O_nxt;
philpem@1 151 reg [MB_WB_ADR_WIDTH-1:0] MB_ADR_O_nxt;
philpem@1 152 reg [MB_WB_DAT_WIDTH/8-1:0] MB_SEL_O_nxt;
philpem@1 153 reg reg_status_nxt;
philpem@1 154 reg burst_start, xfer_done;
philpem@1 155 wire [2:0] iCount;
philpem@1 156 wire [5:0] bCount;
philpem@1 157 wire [8:0] biCount;
philpem@1 158
philpem@1 159 /*----------------------------------------------------------------------
philpem@1 160
philpem@1 161 READ State Machine
philpem@1 162
philpem@1 163 ----------------------------------------------------------------------*/
philpem@1 164 reg [2:0] rstate, rstate_nxt;
philpem@1 165 parameter RD_IDLE = 3'b000;
philpem@1 166 parameter RD_SINGLEA = 3'b001;
philpem@1 167 parameter RD_SINGLEB = 3'b010;
philpem@1 168 parameter RD_SINGLE_RETRY = 3'b011;
philpem@1 169 parameter RD_BURST = 3'b100;
philpem@1 170
philpem@1 171 always @(/*AUTOSENSE*/MA_ACK_I or MA_ERR_I or MA_RTY_I or MB_ERR_I
philpem@1 172 or MB_RTY_I or burst_start or rburst_count or reg_bt3
philpem@1 173 or reg_start or retry_delay or rstate or xfer_done)
philpem@1 174 casez (rstate)
philpem@1 175 RD_IDLE:
philpem@1 176 if (reg_start && (reg_bt3 == 1'b0))
philpem@1 177 rstate_nxt = RD_SINGLEA;
philpem@1 178 else if (burst_start && reg_bt3)
philpem@1 179 rstate_nxt = RD_BURST;
philpem@1 180 else
philpem@1 181 rstate_nxt = rstate;
philpem@1 182
philpem@1 183 RD_SINGLEA:
philpem@1 184 if (MA_ACK_I)
philpem@1 185 rstate_nxt = RD_SINGLEB;
philpem@1 186 else if (MA_ERR_I)
philpem@1 187 rstate_nxt = RD_IDLE;
philpem@1 188 else if (MA_RTY_I)
philpem@1 189 rstate_nxt = RD_SINGLE_RETRY;
philpem@1 190 else
philpem@1 191 rstate_nxt = rstate;
philpem@1 192
philpem@1 193 RD_SINGLEB:
philpem@1 194 if (burst_start)
philpem@1 195 rstate_nxt = RD_SINGLEA;
philpem@1 196 else if (MB_ERR_I || xfer_done)
philpem@1 197 rstate_nxt = RD_IDLE;
philpem@1 198 else if (MB_RTY_I)
philpem@1 199 rstate_nxt = RD_SINGLE_RETRY;
philpem@1 200 else
philpem@1 201 rstate_nxt = rstate;
philpem@1 202
philpem@1 203 RD_BURST:
philpem@1 204 if (MB_ERR_I || MB_RTY_I || MA_ERR_I || MB_RTY_I || (MA_ACK_I && (rburst_count == 0)))
philpem@1 205 rstate_nxt = RD_IDLE;
philpem@1 206 else
philpem@1 207 rstate_nxt = rstate;
philpem@1 208
philpem@1 209 RD_SINGLE_RETRY:
philpem@1 210 if (retry_delay == 8'h0)
philpem@1 211 rstate_nxt = RD_SINGLEA;
philpem@1 212 else
philpem@1 213 rstate_nxt = rstate;
philpem@1 214
philpem@1 215 default:
philpem@1 216 rstate_nxt = RD_IDLE;
philpem@1 217 endcase
philpem@1 218
philpem@1 219 /*----------------------------------------------------------------------
philpem@1 220
philpem@1 221 WRITE State Machine
philpem@1 222
philpem@1 223 ----------------------------------------------------------------------*/
philpem@1 224 reg [3:0] wstate, wstate_nxt;
philpem@1 225 parameter WR_IDLE = 4'b0000;
philpem@1 226 parameter WR_SINGLEA = 4'b0001;
philpem@1 227 parameter WR_SINGLEB = 4'b0010;
philpem@1 228 parameter WR_FIFO_CHECK = 4'b0011;
philpem@1 229 parameter WR_SHORT = 4'b0100;
philpem@1 230 parameter WR_BURST = 4'b0101;
philpem@1 231 parameter WR_SBURST = 4'b0110;
philpem@1 232 parameter WR_SETUPA = 4'b0111;
philpem@1 233 parameter WR_SETUPB = 4'b1000;
philpem@1 234 parameter WR_ERROR = 4'b1001;
philpem@1 235 parameter WR_RETRY = 4'b1010;
philpem@1 236
philpem@1 237 always @(/*AUTOSENSE*/MA_ERR_I or MA_RTY_I or MB_ACK_I or MB_ERR_I
philpem@1 238 or MB_RTY_I or fifo_aempty or fifo_empty or iCount
philpem@1 239 or reg_bt3 or reg_start or retry_delay or wburst_count
philpem@1 240 or wstate or xfer_length)
philpem@1 241 casez (wstate)
philpem@1 242 WR_IDLE:
philpem@1 243 if (reg_start)
philpem@1 244 wstate_nxt = reg_bt3 ? WR_SETUPA : WR_SINGLEA;
philpem@1 245 else
philpem@1 246 wstate_nxt = wstate;
philpem@1 247
philpem@1 248 WR_SINGLEA:
philpem@1 249 if (MA_ERR_I)
philpem@1 250 wstate_nxt = WR_IDLE;
philpem@1 251 else if (fifo_empty == 1'b0)
philpem@1 252 wstate_nxt = WR_SINGLEB;
philpem@1 253 else
philpem@1 254 wstate_nxt = wstate;
philpem@1 255
philpem@1 256 WR_SINGLEB:
philpem@1 257 if (MB_ACK_I)
philpem@1 258 wstate_nxt = (xfer_length == iCount) ? WR_IDLE : WR_SINGLEA;
philpem@1 259 else if (MB_ERR_I)
philpem@1 260 wstate_nxt = WR_IDLE;
philpem@1 261 else if (MB_RTY_I)
philpem@1 262 wstate_nxt = WR_SINGLEA;
philpem@1 263 else
philpem@1 264 wstate_nxt = wstate;
philpem@1 265
philpem@1 266 WR_FIFO_CHECK:
philpem@1 267 if (MA_ERR_I)
philpem@1 268 wstate_nxt = WR_ERROR;
philpem@1 269 else if (MA_RTY_I)
philpem@1 270 wstate_nxt = WR_RETRY;
philpem@1 271 else
philpem@1 272 if ((fifo_empty == 1'b0) && (wburst_count == 6'h0))
philpem@1 273 wstate_nxt = WR_SHORT;
philpem@1 274 else if ((fifo_aempty == 1'b0) && (wburst_count >= 6'h1))
philpem@1 275 wstate_nxt = WR_BURST;
philpem@1 276 else
philpem@1 277 wstate_nxt = wstate;
philpem@1 278
philpem@1 279 WR_SHORT:
philpem@1 280 if (MA_ERR_I)
philpem@1 281 wstate_nxt = WR_ERROR;
philpem@1 282 else if (MA_RTY_I)
philpem@1 283 wstate_nxt = WR_RETRY;
philpem@1 284 else
philpem@1 285 if (MB_ACK_I)
philpem@1 286 wstate_nxt = WR_FIFO_CHECK;
philpem@1 287 else if (MB_ERR_I)
philpem@1 288 wstate_nxt = WR_ERROR;
philpem@1 289 else if (MB_RTY_I)
philpem@1 290 wstate_nxt = WR_RETRY;
philpem@1 291 else
philpem@1 292 wstate_nxt = wstate;
philpem@1 293
philpem@1 294 WR_BURST:
philpem@1 295 if (MA_ERR_I)
philpem@1 296 wstate_nxt = WR_ERROR;
philpem@1 297 else if (MA_RTY_I)
philpem@1 298 wstate_nxt = WR_RETRY;
philpem@1 299 else
philpem@1 300 if (MB_ACK_I)
philpem@1 301 if (fifo_aempty && (wburst_count >= 6'h2))
philpem@1 302 wstate_nxt = WR_SBURST;
philpem@1 303 else if (wburst_count == 6'h0)
philpem@1 304 wstate_nxt = WR_SETUPA;
philpem@1 305 else
philpem@1 306 wstate_nxt = wstate;
philpem@1 307 else if (MB_ERR_I)
philpem@1 308 wstate_nxt = WR_ERROR;
philpem@1 309 else if (MB_RTY_I)
philpem@1 310 wstate_nxt = WR_RETRY;
philpem@1 311 else
philpem@1 312 wstate_nxt = wstate;
philpem@1 313
philpem@1 314 WR_SBURST:
philpem@1 315 if (MA_ERR_I)
philpem@1 316 wstate_nxt = WR_ERROR;
philpem@1 317 else if (MA_RTY_I)
philpem@1 318 wstate_nxt = WR_RETRY;
philpem@1 319 else
philpem@1 320 if (MB_ACK_I)
philpem@1 321 wstate_nxt = WR_FIFO_CHECK;
philpem@1 322 else if (MB_RTY_I)
philpem@1 323 wstate_nxt = WR_RETRY;
philpem@1 324 else
philpem@1 325 wstate_nxt = wstate;
philpem@1 326
philpem@1 327 WR_SETUPA:
philpem@1 328 wstate_nxt = WR_SETUPB;
philpem@1 329
philpem@1 330 WR_SETUPB:
philpem@1 331 wstate_nxt = (wburst_count == 6'h0) ? WR_IDLE : WR_FIFO_CHECK;
philpem@1 332
philpem@1 333 WR_ERROR:
philpem@1 334 wstate_nxt = fifo_empty ? WR_IDLE : wstate;
philpem@1 335
philpem@1 336 WR_RETRY:
philpem@1 337 if (fifo_empty && (retry_delay == 8'h0))
philpem@1 338 wstate_nxt = WR_FIFO_CHECK;
philpem@1 339 else
philpem@1 340 wstate_nxt = wstate;
philpem@1 341
philpem@1 342 default:
philpem@1 343 wstate_nxt = WR_IDLE;
philpem@1 344 endcase
philpem@1 345
philpem@1 346 /*----------------------------------------------------------------------
philpem@1 347 Status Signals
philpem@1 348 ----------------------------------------------------------------------*/
philpem@1 349 always @(/*AUTOSENSE*/MA_ERR_I or MB_ERR_I or reg_status or wstate
philpem@1 350 or wstate_nxt)
philpem@1 351 begin
philpem@1 352 // Raise and hold busy signal until current DMA transfer is complete
philpem@1 353 reg_busy = (wstate_nxt != WR_IDLE);
philpem@1 354
philpem@1 355 // Raise and hold error signal until a new DMA transfer is initiated.
philpem@1 356 // Error signal is raised when the WISHBONE cycle results in _ERR_I
philpem@1 357 if ((wstate == WR_IDLE) && (wstate_nxt != WR_IDLE))
philpem@1 358 reg_status_nxt = 1'b0;
philpem@1 359 else if (MA_ERR_I || MB_ERR_I)
philpem@1 360 reg_status_nxt = 1'b1;
philpem@1 361 else
philpem@1 362 reg_status_nxt = reg_status;
philpem@1 363
philpem@1 364 // Raise interrupt on completion of DMA transfer
philpem@1 365 reg_interrupt = (wstate != WR_IDLE) & (wstate_nxt == WR_IDLE);
philpem@1 366 end
philpem@1 367
philpem@1 368 /*----------------------------------------------------------------------
philpem@1 369 WISHBONE Read Port
philpem@1 370 ----------------------------------------------------------------------*/
philpem@1 371 always @(/*AUTOSENSE*/MA_ACK_I or MA_ADR_O or MA_CTI_O or MA_CYC_O
philpem@1 372 or MA_CYC_O_d or MA_ERR_I or MA_RTY_I or MA_STB_O
philpem@1 373 or MB_ERR_I or MB_RTY_I or burst_start or iCount
philpem@1 374 or raddr_checkpoint or rburst_count or reg_00_data
philpem@1 375 or reg_bt3 or reg_s_con or reg_start or rstate
philpem@1 376 or rstate_nxt)
philpem@1 377 begin
philpem@1 378 // MA_CYC_O and MA_STB_O
philpem@1 379
philpem@1 380 // handle all conditions that cause MA_CYC_O to go 0
philpem@1 381 if (((rstate == RD_SINGLEA)
philpem@1 382 && (MA_ACK_I || MA_ERR_I || MA_RTY_I))
philpem@1 383 || ((rstate == RD_BURST)
philpem@1 384 && (MB_ERR_I || MB_RTY_I || (MA_ACK_I && (rburst_count == 6'h0)))))
philpem@1 385 begin
philpem@1 386 MA_CYC_O_nxt = 1'b0;
philpem@1 387 MA_STB_O_nxt = 1'b0;
philpem@1 388 end
philpem@1 389 // handle all conditions that cause MA_CYC_O to go 1
philpem@1 390 else if (((rstate_nxt == RD_SINGLEA)
philpem@1 391 && ((rstate == RD_IDLE) || (rstate == RD_SINGLEB) || (rstate == RD_SINGLE_RETRY)))
philpem@1 392 || ((rstate == RD_BURST) && (MA_CYC_O_d == 1'b0)))
philpem@1 393 begin
philpem@1 394 MA_CYC_O_nxt = 1'b1;
philpem@1 395 MA_STB_O_nxt = 1'b1;
philpem@1 396 end
philpem@1 397 // default: maintain state
philpem@1 398 else
philpem@1 399 begin
philpem@1 400 MA_CYC_O_nxt = MA_CYC_O;
philpem@1 401 MA_STB_O_nxt = MA_STB_O;
philpem@1 402 end
philpem@1 403
philpem@1 404
philpem@1 405 // MA_ADR_O
philpem@1 406
philpem@1 407 // set up first address of the dma transfer
philpem@1 408 if (reg_start)
philpem@1 409 MA_ADR_O_nxt = reg_00_data;
philpem@1 410 else if (reg_s_con == 1'b0)
philpem@1 411 begin
philpem@1 412 // roll back to first address in a burst transfer on a retry
philpem@1 413 if (/*(rstate == RD_BURST) && */MB_RTY_I)
philpem@1 414 MA_ADR_O_nxt = raddr_checkpoint;
philpem@1 415 // increment for every regular transfer
philpem@1 416 else if ((MB_RTY_I == 1'b0)
philpem@1 417 && (((rstate == RD_SINGLEB) && burst_start)
philpem@1 418 || ((rstate == RD_BURST) && MA_ACK_I)))
philpem@1 419 MA_ADR_O_nxt = MA_ADR_O + iCount;
philpem@1 420 else
philpem@1 421 MA_ADR_O_nxt = MA_ADR_O;
philpem@1 422 end
philpem@1 423 else
philpem@1 424 MA_ADR_O_nxt = MA_ADR_O;
philpem@1 425
philpem@1 426
philpem@1 427 // MA_CTI_O
philpem@1 428
philpem@1 429 if (reg_start || burst_start)
philpem@1 430 MA_CTI_O_nxt = reg_bt3 ? (reg_s_con ? 3'b001 : 3'b010) : 3'b000;
philpem@1 431 else if ((rstate == RD_BURST) && (rburst_count == 6'h1) && MA_ACK_I)
philpem@1 432 MA_CTI_O_nxt = 3'b111;
philpem@1 433 else
philpem@1 434 MA_CTI_O_nxt = MA_CTI_O;
philpem@1 435
philpem@1 436
philpem@1 437 // Other signals
philpem@1 438 MA_WE_O = 1'b0;
philpem@1 439 MA_DAT_O = 0;
philpem@1 440 MA_LOCK_O = 1'b0;
philpem@1 441 end
philpem@1 442
philpem@1 443 generate
philpem@1 444 if (MA_WB_DAT_WIDTH == 8) begin
philpem@1 445
philpem@1 446 always @(*)
philpem@1 447 MA_SEL_O_nxt = 1'b1;
philpem@1 448
philpem@1 449 end
philpem@1 450 else begin
philpem@1 451
philpem@1 452 always @(/*AUTOSENSE*/MA_ADR_O_nxt or iCount)
philpem@1 453 begin
philpem@1 454 if (iCount == 1)
philpem@1 455 casez (MA_ADR_O_nxt[1:0])
philpem@1 456 2'b00: MA_SEL_O_nxt = 4'b1000;
philpem@1 457 2'b01: MA_SEL_O_nxt = 4'b0100;
philpem@1 458 2'b10: MA_SEL_O_nxt = 4'b0010;
philpem@1 459 2'b11: MA_SEL_O_nxt = 4'b0001;
philpem@1 460 default:
philpem@1 461 MA_SEL_O_nxt = 4'b1111;
philpem@1 462 endcase
philpem@1 463 else if (iCount == 2)
philpem@1 464 MA_SEL_O_nxt = MA_ADR_O_nxt[1] ? 4'b0011 : 4'b1100;
philpem@1 465 else
philpem@1 466 MA_SEL_O_nxt = 4'b1111;
philpem@1 467 end
philpem@1 468
philpem@1 469 end
philpem@1 470 endgenerate
philpem@1 471
philpem@1 472
philpem@1 473 /*----------------------------------------------------------------------
philpem@1 474 WISHBONE Write Port
philpem@1 475 ----------------------------------------------------------------------*/
philpem@1 476 always @(/*AUTOSENSE*/MA_ERR_I or MA_RTY_I or MB_ACK_I or MB_ADR_O
philpem@1 477 or MB_CTI_O or MB_CYC_O or MB_ERR_I or MB_RTY_I
philpem@1 478 or MB_STB_O or fifo_aempty or fifo_dout or fifo_empty
philpem@1 479 or iCount or reg_04_data or reg_d_con or reg_s_con
philpem@1 480 or reg_start or waddr_checkpoint or wburst_count or wstate
philpem@1 481 or wstate_nxt)
philpem@1 482 begin
philpem@1 483 // MB_CYC_O and MB_STB_O
philpem@1 484
philpem@1 485 // handle all conditions that cause MB_CYC_O to go 0
philpem@1 486 if (((wstate == WR_SINGLEB)
philpem@1 487 && (MB_ACK_I || MB_ERR_I || MB_RTY_I))
philpem@1 488 || ((MA_ERR_I || MA_RTY_I)
philpem@1 489 && ((wstate == WR_SHORT) || (wstate == WR_FIFO_CHECK) || (wstate == WR_BURST) || (wstate == WR_SBURST)))
philpem@1 490 || ((wstate == WR_BURST)
philpem@1 491 && ((MB_ACK_I && (wburst_count == 6'h0)) || MB_ERR_I || MB_RTY_I))
philpem@1 492 || ((wstate == WR_SBURST)
philpem@1 493 && (MB_ACK_I || MB_ERR_I || MB_RTY_I)))
philpem@1 494 begin
philpem@1 495 MB_CYC_O_nxt = 1'b0;
philpem@1 496 MB_STB_O_nxt = 1'b0;
philpem@1 497 end
philpem@1 498 // handle all conditions that cause MB_CYC_O to go 1
philpem@1 499 else if (((wstate == WR_SINGLEA) && (fifo_empty == 1'b0))
philpem@1 500 || ((wstate == WR_FIFO_CHECK)
philpem@1 501 && (((fifo_empty == 1'b0) && (wburst_count == 6'h0))
philpem@1 502 || ((fifo_aempty == 1'b0) && (wburst_count >= 6'h1)))))
philpem@1 503 begin
philpem@1 504 MB_CYC_O_nxt = 1'b1;
philpem@1 505 MB_STB_O_nxt = 1'b1;
philpem@1 506 end
philpem@1 507 // default: maintain state
philpem@1 508 else
philpem@1 509 begin
philpem@1 510 MB_CYC_O_nxt = MB_CYC_O;
philpem@1 511 MB_STB_O_nxt = MB_STB_O;
philpem@1 512 end
philpem@1 513
philpem@1 514
philpem@1 515 // MB_ADR_O
philpem@1 516
philpem@1 517 // set up first address of the dma transfer
philpem@1 518 if (reg_start)
philpem@1 519 MB_ADR_O_nxt = reg_04_data;
philpem@1 520 else if (reg_d_con == 1'b0)
philpem@1 521 begin
philpem@1 522 // roll back to first address in a burst transfer on a retry
philpem@1 523 if (wstate == WR_RETRY)
philpem@1 524 MB_ADR_O_nxt = waddr_checkpoint;
philpem@1 525 // increment for every regular transfer
philpem@1 526 else if (((wstate == WR_SINGLEB) && MB_ACK_I)
philpem@1 527 || (MB_ACK_I && (MA_RTY_I == 1'b0) && (MA_ERR_I == 1'b0)
philpem@1 528 && ((wstate == WR_SHORT) || (wstate == WR_BURST) || (wstate == WR_SBURST))))
philpem@1 529 MB_ADR_O_nxt = MB_ADR_O + iCount;
philpem@1 530 else
philpem@1 531 MB_ADR_O_nxt = MB_ADR_O;
philpem@1 532 end
philpem@1 533 else
philpem@1 534 MB_ADR_O_nxt = MB_ADR_O;
philpem@1 535
philpem@1 536
philpem@1 537 // MB_CTI_O
philpem@1 538
philpem@1 539 // set up classic wishbone cycle
philpem@1 540 if ((wstate == WR_SINGLEA)
philpem@1 541 || ((wstate == WR_FIFO_CHECK) && (wstate_nxt == WR_SHORT)))
philpem@1 542 MB_CTI_O_nxt = 3'b000;
philpem@1 543 // set up termination of a wishbone burst cycle
philpem@1 544 else if ((wstate == WR_BURST)
philpem@1 545 && ((MB_ACK_I && (wburst_count == 6'h1)) || (wstate_nxt == WR_SBURST)))
philpem@1 546 MB_CTI_O_nxt = 3'b111;
philpem@1 547 // set up wishbone burst (incrementing or constant address)
philpem@1 548 else if (((wstate == WR_FIFO_CHECK) && (wstate_nxt == WR_BURST))
philpem@1 549 || ((wstate == WR_BURST) && MB_ACK_I))
philpem@1 550 MB_CTI_O_nxt = reg_s_con ? 3'b001 : 3'b010;
philpem@1 551 // hold
philpem@1 552 else
philpem@1 553 MB_CTI_O_nxt = MB_CTI_O;
philpem@1 554
philpem@1 555 // MB_DAT_O
philpem@1 556 MB_DAT_O = fifo_dout;
philpem@1 557
philpem@1 558
philpem@1 559 // Other signals
philpem@1 560 MB_WE_O = 1'b1;
philpem@1 561 MB_LOCK_O = 1'b0;
philpem@1 562 end
philpem@1 563
philpem@1 564 generate
philpem@1 565 if (MB_WB_DAT_WIDTH == 8) begin
philpem@1 566
philpem@1 567 always @(*)
philpem@1 568 MB_SEL_O_nxt = 1'b1;
philpem@1 569
philpem@1 570 end
philpem@1 571 else begin
philpem@1 572
philpem@1 573 always @(/*AUTOSENSE*/MB_ADR_O_nxt or iCount)
philpem@1 574 begin
philpem@1 575 if (iCount == 1)
philpem@1 576 casez (MB_ADR_O_nxt[1:0])
philpem@1 577 2'b00: MB_SEL_O_nxt = 4'b1000;
philpem@1 578 2'b01: MB_SEL_O_nxt = 4'b0100;
philpem@1 579 2'b10: MB_SEL_O_nxt = 4'b0010;
philpem@1 580 2'b11: MB_SEL_O_nxt = 4'b0001;
philpem@1 581 default:
philpem@1 582 MB_SEL_O_nxt = 4'b1111;
philpem@1 583 endcase
philpem@1 584 else if (iCount == 2)
philpem@1 585 MB_SEL_O_nxt = MB_ADR_O_nxt[1] ? 4'b0011 : 4'b1100;
philpem@1 586 else
philpem@1 587 MB_SEL_O_nxt = 4'b1111;
philpem@1 588 end
philpem@1 589
philpem@1 590 end
philpem@1 591 endgenerate
philpem@1 592
philpem@1 593 /*----------------------------------------------------------------------
philpem@1 594 Logic to keep track of where we are in the transfer process
philpem@1 595 ----------------------------------------------------------------------*/
philpem@1 596 // Increment Count
philpem@1 597 generate
philpem@1 598 if (S_WB_DAT_WIDTH == 8) begin
philpem@1 599 assign iCount = 3'h1;
philpem@1 600 end
philpem@1 601 else begin
philpem@1 602 assign iCount = reg_incw ? 3'h4 : (reg_inchw ? 3'h2 : 3'h1);
philpem@1 603 end
philpem@1 604 endgenerate
philpem@1 605
philpem@1 606 // Burst Count
philpem@1 607 assign bCount = (reg_bt3
philpem@1 608 ? (reg_bt2
philpem@1 609 ? 6'h3f
philpem@1 610 : (reg_bt1
philpem@1 611 ? (reg_bt0 ? 6'h1f : 6'h0f)
philpem@1 612 : (reg_bt0 ? 6'h07 : 6'h03)))
philpem@1 613 : 6'h01
philpem@1 614 );
philpem@1 615
philpem@1 616 // Burst Increment Count
philpem@1 617 assign biCount = (reg_bt3
philpem@1 618 ? (reg_bt2
philpem@1 619 ? iCount<<6
philpem@1 620 : (reg_bt1
philpem@1 621 ? (reg_bt0 ? iCount<<5 : iCount<<4)
philpem@1 622 : (reg_bt0 ? iCount<<3 : iCount<<2)
philpem@1 623 )
philpem@1 624 )
philpem@1 625 : iCount
philpem@1 626 );
philpem@1 627
philpem@1 628 always @(/*AUTOSENSE*/MA_ACK_I or MB_ACK_I or bCount or biCount
philpem@1 629 or fifo_empty or iCount or rburst_count or reg_08_data
philpem@1 630 or reg_inchw or reg_incw or reg_start or rstate
philpem@1 631 or save_wburst_count or wburst_count or wstate
philpem@1 632 or xfer_length)
philpem@1 633 begin
philpem@1 634 // Transfer Length
philpem@1 635 if (reg_start && (wstate == WR_IDLE))
philpem@1 636 xfer_length_nxt = reg_08_data;
philpem@1 637 else if (MB_ACK_I && (wstate == WR_SINGLEB))
philpem@1 638 xfer_length_nxt = xfer_length - iCount;
philpem@1 639 else if (wstate == WR_SETUPA)
philpem@1 640 xfer_length_nxt = (xfer_length >= biCount) ? (xfer_length - biCount) : 0;
philpem@1 641 else
philpem@1 642 xfer_length_nxt = xfer_length;
philpem@1 643
philpem@1 644 // Read-side Burst Count
philpem@1 645 if (rstate == RD_IDLE)
philpem@1 646 rburst_count_nxt = wburst_count;
philpem@1 647 else if ((rstate == RD_BURST) && MA_ACK_I)
philpem@1 648 rburst_count_nxt = rburst_count - 1'b1;
philpem@1 649 else
philpem@1 650 rburst_count_nxt = rburst_count;
philpem@1 651
philpem@1 652 // Write-side Burst Count
philpem@1 653 if (wstate == WR_SETUPA)
philpem@1 654 wburst_count_nxt = ((xfer_length == 0)
philpem@1 655 ? 0
philpem@1 656 : ((xfer_length >= biCount)
philpem@1 657 ? bCount
philpem@1 658 : (xfer_length-1)>>(reg_incw ? 2 : (reg_inchw ? 1 : 0))));
philpem@1 659 else if ((wstate == WR_RETRY) && fifo_empty)
philpem@1 660 wburst_count_nxt = save_wburst_count;
philpem@1 661 else if (MB_ACK_I
philpem@1 662 && ((wstate == WR_SHORT) || (wstate == WR_BURST) || (wstate == WR_SBURST)))
philpem@1 663 wburst_count_nxt = wburst_count - 1'b1;
philpem@1 664 else
philpem@1 665 wburst_count_nxt = wburst_count;
philpem@1 666 end
philpem@1 667
philpem@1 668 /*----------------------------------------------------------------------
philpem@1 669 Logic to support a burst retry
philpem@1 670 ----------------------------------------------------------------------*/
philpem@1 671 always @(/*AUTOSENSE*/MA_ADR_O or MB_ADR_O or raddr_checkpoint
philpem@1 672 or reg_rdelay or retry_delay or rstate or rstate_nxt
philpem@1 673 or save_wburst_count or waddr_checkpoint
philpem@1 674 or wburst_count_nxt or wstate or wstate_nxt)
philpem@1 675 begin
philpem@1 676 // Write-side Saved Burst Count
philpem@1 677 if (wstate == WR_SETUPA)
philpem@1 678 save_wburst_count_nxt = wburst_count_nxt;
philpem@1 679 else
philpem@1 680 save_wburst_count_nxt = save_wburst_count;
philpem@1 681
philpem@1 682 // Retry Delay
philpem@1 683 if (((wstate != WR_RETRY) && (wstate_nxt == WR_RETRY))
philpem@1 684 || ((rstate == RD_SINGLEA) && (rstate_nxt == RD_SINGLE_RETRY)))
philpem@1 685 retry_delay_nxt = reg_rdelay;
philpem@1 686 else if ((wstate == WR_RETRY) || (rstate == RD_SINGLE_RETRY))
philpem@1 687 retry_delay_nxt = retry_delay - 1'b1;
philpem@1 688 else
philpem@1 689 retry_delay_nxt = retry_delay;
philpem@1 690
philpem@1 691 // Read Address Checkpoint
philpem@1 692 if ((rstate == RD_IDLE) && (rstate_nxt == RD_BURST))
philpem@1 693 raddr_checkpoint_nxt = MA_ADR_O;
philpem@1 694 else
philpem@1 695 raddr_checkpoint_nxt = raddr_checkpoint;
philpem@1 696
philpem@1 697 // Write Address Checkpoint
philpem@1 698 if (wstate == WR_SETUPA)
philpem@1 699 waddr_checkpoint_nxt = MB_ADR_O;
philpem@1 700 else
philpem@1 701 waddr_checkpoint_nxt = waddr_checkpoint;
philpem@1 702 end
philpem@1 703
philpem@1 704 /*----------------------------------------------------------------------
philpem@1 705 Logic to indicate start/end of transfer and bursts
philpem@1 706 ----------------------------------------------------------------------*/
philpem@1 707 always @(/*AUTOSENSE*/MA_ERR_I or MB_ACK_I or MB_ERR_I or iCount
philpem@1 708 or retry_delay or wburst_count or wstate or xfer_length)
philpem@1 709 begin
philpem@1 710 if (((wstate == WR_SINGLEB) && (xfer_length > iCount) && MB_ACK_I)
philpem@1 711 || ((wstate == WR_SETUPB) && (wburst_count > 0))
philpem@1 712 || ((wstate == WR_RETRY) && (retry_delay == 8'b0)))
philpem@1 713 burst_start = 1'b1;
philpem@1 714 else
philpem@1 715 burst_start = 1'b0;
philpem@1 716
philpem@1 717 if (MB_ERR_I
philpem@1 718 || MA_ERR_I
philpem@1 719 || ((wstate == WR_SINGLEB) && (xfer_length == iCount) && MB_ACK_I)
philpem@1 720 || ((wstate == WR_SETUPB) && (wburst_count == 0)))
philpem@1 721 xfer_done = 1'b1;
philpem@1 722 else
philpem@1 723 xfer_done = 1'b0;
philpem@1 724 end
philpem@0 725
philpem@1 726 /*----------------------------------------------------------------------
philpem@1 727 Sequential Logic
philpem@1 728 ----------------------------------------------------------------------*/
philpem@0 729 always @(posedge CLK_I or posedge RST_I)
philpem@1 730 if (RST_I)
philpem@0 731 begin
philpem@1 732 rstate <= #UDLY RD_IDLE;
philpem@1 733 wstate <= #UDLY WR_IDLE;
philpem@1 734 xfer_length <= #UDLY 32'b0;
philpem@1 735 rburst_count <= #UDLY 6'b0;
philpem@1 736 wburst_count <= #UDLY 6'b0;
philpem@1 737 retry_delay <= #UDLY 8'b0;
philpem@1 738 reg_status <= #UDLY 1'b0;
philpem@1 739 MA_CYC_O <= #UDLY 1'b0;
philpem@1 740 MA_CYC_O_d <= #UDLY 1'b0;
philpem@1 741 MA_STB_O <= #UDLY 1'b0;
philpem@1 742 MA_CTI_O <= #UDLY 3'b0;
philpem@1 743 MA_ADR_O <= #UDLY 'b0;
philpem@1 744 MA_SEL_O <= #UDLY 'b0;
philpem@1 745 MB_CYC_O <= #UDLY 1'b0;
philpem@1 746 MB_CYC_O_d <= #UDLY 1'b0;
philpem@1 747 MB_STB_O <= #UDLY 1'b0;
philpem@1 748 MB_CTI_O <= #UDLY 3'b0;
philpem@1 749 MB_ADR_O <= #UDLY 'b0;
philpem@1 750 MB_SEL_O <= #UDLY 'b0;
philpem@1 751 raddr_checkpoint <= #UDLY 32'b0;
philpem@1 752 waddr_checkpoint <= #UDLY 32'b0;
philpem@1 753 save_wburst_count <= #UDLY 6'b0;
philpem@0 754 end
philpem@1 755 else
philpem@0 756 begin
philpem@1 757 rstate <= #UDLY rstate_nxt;
philpem@1 758 wstate <= #UDLY wstate_nxt;
philpem@1 759 xfer_length <= #UDLY xfer_length_nxt;
philpem@1 760 rburst_count <= #UDLY rburst_count_nxt;
philpem@1 761 wburst_count <= #UDLY wburst_count_nxt;
philpem@1 762 retry_delay <= #UDLY retry_delay_nxt;
philpem@1 763 reg_status <= #UDLY reg_status_nxt;
philpem@1 764 MA_CYC_O <= #UDLY MA_CYC_O_nxt;
philpem@1 765 MA_CYC_O_d <= #UDLY MA_CYC_O;
philpem@1 766 MA_STB_O <= #UDLY MA_STB_O_nxt;
philpem@1 767 MA_CTI_O <= #UDLY MA_CTI_O_nxt;
philpem@1 768 MA_ADR_O <= #UDLY MA_ADR_O_nxt;
philpem@1 769 MA_SEL_O <= #UDLY MA_SEL_O_nxt;
philpem@1 770 MB_CYC_O <= #UDLY MB_CYC_O_nxt;
philpem@1 771 MB_CYC_O_d <= #UDLY MB_CYC_O;
philpem@1 772 MB_STB_O <= #UDLY MB_STB_O_nxt;
philpem@1 773 MB_CTI_O <= #UDLY MB_CTI_O_nxt;
philpem@1 774 MB_ADR_O <= #UDLY MB_ADR_O_nxt;
philpem@1 775 MB_SEL_O <= #UDLY MB_SEL_O_nxt;
philpem@1 776 raddr_checkpoint <= #UDLY raddr_checkpoint_nxt;
philpem@1 777 waddr_checkpoint <= #UDLY waddr_checkpoint_nxt;
philpem@1 778 save_wburst_count <= #UDLY save_wburst_count_nxt;
philpem@0 779 end
philpem@0 780
philpem@1 781 /*----------------------------------------------------------------------
philpem@1 782 FIFO Logic
philpem@1 783 ----------------------------------------------------------------------*/
philpem@1 784 reg fifo_rd_en, fifo_wr_en;
philpem@1 785 always @(/*AUTOSENSE*/MA_ACK_I or MA_DAT_I or MB_ACK_I
philpem@1 786 or fifo_aempty or fifo_empty or rstate or wburst_count
philpem@1 787 or wstate)
philpem@1 788 begin
philpem@1 789 if (((wstate == WR_SINGLEA) && (fifo_empty == 1'b0))
philpem@1 790 || ((wstate == WR_FIFO_CHECK)
philpem@1 791 && (((fifo_empty == 1'b0) && (wburst_count == 6'h0))
philpem@1 792 || ((fifo_aempty == 1'b0) && (wburst_count >= 6'h1))))
philpem@1 793 || ((wstate == WR_BURST)
philpem@1 794 && (/*(MB_CYC_O_d == 1'b0)
philpem@1 795 ||*/ (MB_ACK_I && (wburst_count >= 6'h1))))
philpem@1 796 || ((wstate == WR_ERROR) && (fifo_empty == 1'b0))
philpem@1 797 || ((wstate == WR_RETRY) && (fifo_empty == 1'b0)))
philpem@1 798 fifo_rd_en = 1'b1;
philpem@1 799 else
philpem@1 800 fifo_rd_en = 1'b0;
philpem@1 801
philpem@1 802 if (MA_ACK_I
philpem@1 803 && ((rstate == RD_SINGLEA) || (rstate == RD_BURST)))
philpem@1 804 fifo_wr_en = 1'b1;
philpem@1 805 else
philpem@1 806 fifo_wr_en = 1'b0;
philpem@1 807
philpem@1 808 fifo_din = MA_DAT_I;
philpem@1 809 end
philpem@1 810
philpem@0 811 generate
philpem@0 812 if (lat_family == "SC" || lat_family == "SCM") begin
philpem@1 813
philpem@1 814 pmi_fifo_dc
philpem@1 815 #(.pmi_data_width_w(MA_WB_DAT_WIDTH),
philpem@1 816 .pmi_data_width_r(MA_WB_DAT_WIDTH),
philpem@1 817 .pmi_data_depth_w(64),
philpem@1 818 .pmi_data_depth_r(64),
philpem@1 819 .pmi_full_flag(64),
philpem@1 820 .pmi_empty_flag(0),
philpem@1 821 .pmi_almost_full_flag(60),
philpem@1 822 .pmi_almost_empty_flag(4),
philpem@1 823 .pmi_regmode("noreg"),
philpem@1 824 .pmi_family(`LATTICE_FAMILY),
philpem@1 825 .module_type("pmi_fifo_dc"),
philpem@1 826 .pmi_implementation(FIFO_IMPLEMENTATION))
philpem@1 827 dma_fifo_dc
philpem@1 828 (
philpem@1 829 .Data(fifo_din),
philpem@1 830 .WrClock (CLK_I),
philpem@1 831 .RdClock (CLK_I),
philpem@1 832 .WrEn (fifo_wr_en),
philpem@1 833 .RdEn (fifo_rd_en),
philpem@1 834 .Reset (RST_I),
philpem@1 835 .RPReset (RST_I),
philpem@1 836 .Q (fifo_dout),
philpem@1 837 .Empty (fifo_empty),
philpem@1 838 .Full (),
philpem@1 839 .AlmostEmpty(),
philpem@1 840 .AlmostFull ());
philpem@1 841
philpem@1 842 end else if (lat_family == "MachXO2") begin
philpem@1 843
philpem@1 844 pmi_fifo_dc
philpem@1 845 #(.pmi_data_width_w (MA_WB_DAT_WIDTH),
philpem@1 846 .pmi_data_width_r (MA_WB_DAT_WIDTH),
philpem@1 847 .pmi_data_depth_w (64),
philpem@1 848 .pmi_data_depth_r (64),
philpem@1 849 .pmi_full_flag (64),
philpem@1 850 .pmi_empty_flag (0),
philpem@1 851 .pmi_almost_full_flag (60),
philpem@1 852 .pmi_almost_empty_flag (1),
philpem@1 853 .pmi_regmode ("noreg"),
philpem@1 854 .pmi_family ("XO2"),
philpem@1 855 .module_type ("pmi_fifo_dc"),
philpem@1 856 .pmi_implementation (FIFO_IMPLEMENTATION))
philpem@1 857 dma_fifo
philpem@1 858 (.Data (fifo_din),
philpem@1 859 .WrClock (CLK_I),
philpem@1 860 .RdClock (CLK_I),
philpem@1 861 .WrEn (fifo_wr_en),
philpem@1 862 .RdEn (fifo_rd_en),
philpem@1 863 .Reset (RST_I),
philpem@1 864 .RPReset (RST_I),
philpem@1 865 .Q (fifo_dout),
philpem@1 866 .Empty (fifo_empty),
philpem@1 867 .Full (),
philpem@1 868 .AlmostEmpty(fifo_aempty),
philpem@1 869 .AlmostFull ());
philpem@0 870
philpem@0 871 end else begin
philpem@1 872
philpem@1 873 pmi_fifo
philpem@1 874 #(.pmi_data_width(MA_WB_DAT_WIDTH),
philpem@1 875 .pmi_data_depth(64),
philpem@1 876 .pmi_full_flag(64),
philpem@1 877 .pmi_empty_flag(0),
philpem@1 878 .pmi_almost_full_flag(60),
philpem@1 879 .pmi_almost_empty_flag(1),
philpem@1 880 .pmi_regmode("noreg"),
philpem@1 881 .pmi_family(`LATTICE_FAMILY),
philpem@1 882 .module_type("pmi_fifo"),
philpem@1 883 .pmi_implementation(FIFO_IMPLEMENTATION))
philpem@1 884 dma_fifo
philpem@1 885 (.Data (fifo_din),
philpem@1 886 .Clock (CLK_I),
philpem@1 887 .WrEn (fifo_wr_en),
philpem@1 888 .RdEn (fifo_rd_en),
philpem@1 889 .Reset (RST_I),
philpem@1 890 .Q (fifo_dout),
philpem@1 891 .Empty (fifo_empty),
philpem@1 892 .Full (),
philpem@1 893 .AlmostEmpty(fifo_aempty),
philpem@1 894 .AlmostFull ());
philpem@1 895
philpem@1 896 end
philpem@1 897
philpem@0 898 endgenerate
philpem@0 899
philpem@1 900 endmodule
philpem@0 901
philpem@1 902 `endif // `ifndef MASTER_CTRL_FILE