rtl/verilog/master_ctrl.v

Fri, 13 Aug 2010 10:43:05 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 13 Aug 2010 10:43:05 +0100
changeset 0
11aef665a5d8
child 1
522426d22baa
permissions
-rw-r--r--

Initial commit, DMAC version 3.1

philpem@0 1 // =============================================================================
philpem@0 2 // COPYRIGHT NOTICE
philpem@0 3 // Copyright 2006 (c) Lattice Semiconductor Corporation
philpem@0 4 // ALL RIGHTS RESERVED
philpem@0 5 // This confidential and proprietary software may be used only as authorised by
philpem@0 6 // a licensing agreement from Lattice Semiconductor Corporation.
philpem@0 7 // The entire notice above must be reproduced on all authorized copies and
philpem@0 8 // copies may only be made to the extent permitted by a licensing agreement from
philpem@0 9 // Lattice Semiconductor Corporation.
philpem@0 10 //
philpem@0 11 // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
philpem@0 12 // 5555 NE Moore Court 408-826-6000 (other locations)
philpem@0 13 // Hillsboro, OR 97124 web : http://www.latticesemi.com/
philpem@0 14 // U.S.A email: techsupport@latticesemi.com
philpem@0 15 // =============================================================================/
philpem@0 16 // FILE DETAILS
philpem@0 17 // Project : LM32 DMA Component
philpem@0 18 // File : master_ctrl.v
philpem@0 19 // Title : DMA Master controller
philpem@0 20 // Dependencies : None
philpem@0 21 //
philpem@0 22 // Version 3.1
philpem@0 23 // 1. Make DMA Engine compliant to Rule 3.100 of Wishbone Spec which defines
philpem@0 24 // alignement of bytes in sub-word transfers.
philpem@0 25 // 2. Removed glitch that did not pause the burst write when the read burst
philpem@0 26 // was paused by the "read slave".
philpem@0 27 //
philpem@0 28 // Version 7.0SP2, 3.0
philpem@0 29 // 1. Read and Write channel of DMA controller are working in parallel,
philpem@0 30 // due to that now as soon as FIFO is not empty write channel of the DMA
philpem@0 31 // controller start writing data to the slave.
philpem@0 32 // 2. Burst Size supported by DMA controller is increased to support bigger
philpem@0 33 // burst (from current value of 4 and 8 to 16 and 32). Now 4 different type
philpem@0 34 // of burst sizes are supported by the DMA controller 4, 8, 16 and 32.
philpem@0 35 // For this Burst Size field of the control register is increased to 2 bits.
philpem@0 36 // 3. Glitch is removed on the S_ACK_O signal.
philpem@0 37 //
philpem@0 38 // Version 7.0
philpem@0 39 // 1. Initial Release
philpem@0 40 //
philpem@0 41 // =============================================================================
philpem@0 42
philpem@0 43 `ifndef MASTER_CTRL_FILE
philpem@0 44 `define MASTER_CTRL_FILE
philpem@0 45 `include "system_conf.v"
philpem@0 46 module MASTER_CTRL
philpem@0 47 #(parameter LENGTH_WIDTH = 16,
philpem@0 48 parameter FIFO_IMPLEMENTATION = "EBR")
philpem@0 49 (
philpem@0 50 //master read port
philpem@0 51 MA_ADR_O,
philpem@0 52 MA_SEL_O,
philpem@0 53 MA_WE_O,
philpem@0 54 MA_STB_O,
philpem@0 55 MA_CYC_O,
philpem@0 56 MA_CTI_O,
philpem@0 57 MA_LOCK_O,
philpem@0 58 MA_DAT_I, //32bits
philpem@0 59 MA_ACK_I,
philpem@0 60 MA_ERR_I,
philpem@0 61 MA_RTY_I,
philpem@0 62 //master write port
philpem@0 63 MB_ADR_O,
philpem@0 64 MB_SEL_O,
philpem@0 65 MB_DAT_O, //32bits
philpem@0 66 MB_WE_O,
philpem@0 67 MB_STB_O,
philpem@0 68 MB_CYC_O,
philpem@0 69 MB_CTI_O,
philpem@0 70 MB_LOCK_O,
philpem@0 71 MB_ACK_I,
philpem@0 72 MB_ERR_I,
philpem@0 73 MB_RTY_I,
philpem@0 74 //register interface
philpem@0 75 M_SEL_O,
philpem@0 76 reg_start,
philpem@0 77 reg_status,
philpem@0 78 reg_interrupt,
philpem@0 79 reg_busy,
philpem@0 80 data_length,
philpem@0 81 reg_cntlg,
philpem@0 82 reg_bt2,reg_bt1,reg_bt0,
philpem@0 83 incr_unit,
philpem@0 84 reg_s_con,
philpem@0 85 reg_d_con,
philpem@0 86 reg_00_data,
philpem@0 87 reg_04_data,
philpem@0 88 //system clock and reset
philpem@0 89 CLK_I,
philpem@0 90 RST_I
philpem@0 91 );
philpem@0 92 //master read port
philpem@0 93 output [31:0] MA_ADR_O;
philpem@0 94 output [3:0] MA_SEL_O;
philpem@0 95 output MA_WE_O;
philpem@0 96 output MA_STB_O;
philpem@0 97 output MA_CYC_O;
philpem@0 98 output [2:0] MA_CTI_O;
philpem@0 99 output MA_LOCK_O;
philpem@0 100 input [31:0] MA_DAT_I; //32bits
philpem@0 101 input MA_ACK_I;
philpem@0 102 input MA_ERR_I;
philpem@0 103 input MA_RTY_I;
philpem@0 104 //master write port
philpem@0 105 output [31:0] MB_ADR_O;
philpem@0 106 output [3:0] MB_SEL_O;
philpem@0 107 output [31:0] MB_DAT_O; //32bits
philpem@0 108 output MB_WE_O;
philpem@0 109 output MB_STB_O;
philpem@0 110 output MB_CYC_O;
philpem@0 111 output [2:0] MB_CTI_O;
philpem@0 112 output MB_LOCK_O;
philpem@0 113 input MB_ACK_I;
philpem@0 114 input MB_ERR_I;
philpem@0 115 input MB_RTY_I;
philpem@0 116
philpem@0 117 //register interface
philpem@0 118 input [3:0] M_SEL_O;
philpem@0 119 input reg_start;
philpem@0 120 output reg_status;
philpem@0 121 output reg_interrupt;
philpem@0 122 output reg_busy;
philpem@0 123 input [LENGTH_WIDTH-1:0] data_length;
philpem@0 124 output reg_cntlg;
philpem@0 125 input reg_bt2,reg_bt1,reg_bt0;
philpem@0 126 input [2:0] incr_unit;
philpem@0 127 input reg_s_con;
philpem@0 128 input reg_d_con;
philpem@0 129 input [31:0] reg_00_data;
philpem@0 130 input [31:0] reg_04_data;
philpem@0 131 //system clock and reset
philpem@0 132 input CLK_I;
philpem@0 133 input RST_I;
philpem@0 134
philpem@0 135 parameter lat_family = `LATTICE_FAMILY;
philpem@0 136 parameter UDLY = 1;
philpem@0 137 //Read FSM States encoding
philpem@0 138 parameter ST_IDLE = 3'b000;
philpem@0 139 parameter ST_READ = 3'b001;
philpem@0 140 parameter ST_RDADDR = 3'b010;
philpem@0 141 parameter ST_RDFIFO = 3'b011;
philpem@0 142 parameter ST_WAIT_WRITE_FINISH = 3'b100;
philpem@0 143
philpem@0 144 //Write FSM States encoding
philpem@0 145 parameter ST_WRITE_IDLE = 4'b0000;
philpem@0 146 parameter ST_WRITE = 4'b0001;
philpem@0 147 parameter ST_WRADDR = 4'b0010;
philpem@0 148 parameter ST_CNTLNGTH = 4'b0011;
philpem@0 149 parameter ST_JUSTICE = 4'b0100;
philpem@0 150 parameter ST_FIFO_EMPTY = 4'b0101;
philpem@0 151 parameter ST_WRITE_WAIT = 4'b0110;
philpem@0 152 parameter ST_FIFO_AEMPTY = 4'b1010;
philpem@0 153 parameter ST_FIFO_RESUME = 4'b1000;
philpem@0 154
philpem@0 155 // FSM for normal data transfer
philpem@0 156 parameter ST_IDLE1 = 3'b000;
philpem@0 157 parameter ST_READ1 = 3'b001;
philpem@0 158 parameter ST_WRITE1 = 3'b010;
philpem@0 159 parameter ST_RDADDR1 = 3'b011;
philpem@0 160 parameter ST_WRADDR1 = 3'b100;
philpem@0 161 parameter ST_CNTLNGTH1 = 3'b101;
philpem@0 162 parameter ST_JUSTICE1 = 3'b110;
philpem@0 163 parameter ST_RDFIFO1 = 3'b111;
philpem@0 164 reg [2:0] status;
philpem@0 165 reg var_length;
philpem@0 166
philpem@0 167
philpem@0 168 //fifo status
philpem@0 169
philpem@0 170 reg [2:0] status1;
philpem@0 171 reg [3:0] status2;
philpem@0 172 reg var_length2;
philpem@0 173 reg var_length1;
philpem@0 174 reg MA_STB_O;
philpem@0 175 reg MB_STB_O;
philpem@0 176 reg MA_CYC_O;
philpem@0 177 reg MB_CYC_O;
philpem@0 178 reg [2:0] MA_CTI_O;
philpem@0 179 reg [2:0] MB_CTI_O;
philpem@0 180 wire MA_WE_O = 1'b0;
philpem@0 181 wire MB_WE_O = 1'b1;
philpem@0 182 reg [31:0] MA_ADR_O;
philpem@0 183 reg [31:0] MB_ADR_O;
philpem@0 184 reg [3:0] MA_SEL_O;
philpem@0 185 reg [3:0] MB_SEL_O;
philpem@0 186 wire MA_LOCK_O = 0; //reg_bt2 ? (status1 == ST_READ) && (!(MA_CTI_O == 3'h7)) : 1'b0;
philpem@0 187 wire MB_LOCK_O = 0; //reg_bt2 ? (status2 == ST_WRITE) && (!(MB_CTI_O == 3'h7)) : 1'b0;
philpem@0 188
philpem@0 189 wire reg_busy = reg_bt2 ? !(status1 == ST_IDLE) : !(status == ST_IDLE1);
philpem@0 190 wire reg_interrupt;
philpem@0 191 wire reg_status;
philpem@0 192
philpem@0 193 wire reg_cntlg;
philpem@0 194 reg start_flag;
philpem@0 195 reg [5:0] burst_size;
philpem@0 196 reg [5:0] burst_cnt;
philpem@0 197 reg fifo_wr;
philpem@0 198 reg fifo_rd;
philpem@0 199 reg [31:0] fifo_din;
philpem@0 200 wire [31:0] fifo_dout;
philpem@0 201 wire fifo_empty;
philpem@0 202 wire fifo_aempty;
philpem@0 203 reg fifo_clear;
philpem@0 204 reg [31:0] first_data;
philpem@0 205 reg first_data_flag;
philpem@0 206 wire [31:0] MB_DAT_O = first_data_flag ? first_data : fifo_dout;
philpem@0 207 reg latch_start;
philpem@0 208
philpem@0 209 reg reg_status1, reg_status2;
philpem@0 210 reg reg_interrupt1, reg_interrupt2;
philpem@0 211 reg end_of_transfer;
philpem@0 212 reg burst_completed;
philpem@0 213 reg donot_start_again;
philpem@0 214 reg [5:0] burst_size2;
philpem@0 215 reg [5:0] burst_cnt2;
philpem@0 216
philpem@0 217 reg reg_cntlg_burst, reg_cntlg_normal;
philpem@0 218 reg reg_status_normal, reg_interrupt_normal;
philpem@0 219 reg direct_data;
philpem@0 220
philpem@0 221 always @(posedge CLK_I or posedge RST_I)
philpem@0 222 if(RST_I)
philpem@0 223 begin
philpem@0 224 first_data <= #UDLY 'h0;
philpem@0 225 first_data_flag <= #UDLY 1'b0;
philpem@0 226 end
philpem@0 227 else if((start_flag || direct_data) & !reg_bt2 & MA_ACK_I)
philpem@0 228 begin
philpem@0 229 first_data <= #UDLY MA_DAT_I;
philpem@0 230 first_data_flag <= #UDLY 1'b1;
philpem@0 231 end
philpem@0 232 else if(first_data_flag & MB_ACK_I)
philpem@0 233 begin
philpem@0 234 first_data_flag <= #UDLY 1'b0;
philpem@0 235 end
philpem@0 236
philpem@0 237 assign reg_status = reg_bt2 ? (reg_status1 | reg_status2) : reg_status_normal;
philpem@0 238 assign reg_interrupt = reg_bt2 ? (reg_interrupt1 | reg_interrupt2) : reg_interrupt_normal;
philpem@0 239 assign reg_cntlg = reg_bt2 ? reg_cntlg_burst : reg_cntlg_normal;
philpem@0 240
philpem@0 241
philpem@0 242 //FSM
philpem@0 243 always @(posedge CLK_I or posedge RST_I)
philpem@0 244 if(RST_I)
philpem@0 245 begin
philpem@0 246 status1 <= #UDLY ST_IDLE;
philpem@0 247 var_length1 <= #UDLY 1'b0;
philpem@0 248 MA_ADR_O <= #UDLY 32'h0;
philpem@0 249 MA_SEL_O <= #UDLY 4'b1111;
philpem@0 250 MA_CYC_O <= #UDLY 1'b0;
philpem@0 251 MA_CTI_O <= #UDLY 3'h0;
philpem@0 252 MA_STB_O <= #UDLY 1'b0;
philpem@0 253 reg_status1 <= #UDLY 1'b0;
philpem@0 254 reg_interrupt1 <= #UDLY 1'b0;
philpem@0 255 start_flag <= #UDLY 1'b0;
philpem@0 256 burst_size <= #UDLY 5'h0;
philpem@0 257 burst_cnt <= #UDLY 5'h0;
philpem@0 258 fifo_clear <= #UDLY 1'b0;
philpem@0 259 latch_start <= #UDLY 1'b0;
philpem@0 260 fifo_wr <= #UDLY 1'b0;
philpem@0 261
philpem@0 262 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 263 MB_ADR_O <= #UDLY 32'h0;
philpem@0 264 MB_SEL_O <= #UDLY 4'b1111;
philpem@0 265 MB_CYC_O <= #UDLY 1'b0;
philpem@0 266 MB_CTI_O <= #UDLY 3'h0;
philpem@0 267 MB_STB_O <= #UDLY 1'b0;
philpem@0 268 reg_status2 <= #UDLY 1'b0;
philpem@0 269 reg_interrupt2 <= #UDLY 1'b0;
philpem@0 270 reg_cntlg_burst <= #UDLY 1'b0;
philpem@0 271 burst_size2 <= #UDLY 5'h0;
philpem@0 272 burst_cnt2 <= #UDLY 5'h0;
philpem@0 273 fifo_rd <= #UDLY 1'b0;
philpem@0 274 end_of_transfer <= #UDLY 1'b0;
philpem@0 275 var_length2 <= #UDLY 1'b0;
philpem@0 276 burst_completed <= #UDLY 1'b0;
philpem@0 277 donot_start_again <= #UDLY 1'b0;
philpem@0 278
philpem@0 279 status <= #UDLY ST_IDLE1;
philpem@0 280 var_length <= #UDLY 1'b0;
philpem@0 281 reg_status_normal <= #UDLY 1'b0;
philpem@0 282 reg_interrupt_normal <= #UDLY 1'b0;
philpem@0 283 reg_cntlg_normal <= #UDLY 1'b0;
philpem@0 284 direct_data <= #UDLY 1'b0;
philpem@0 285 end
philpem@0 286 else
philpem@0 287 begin
philpem@0 288 if (reg_bt2) begin
philpem@0 289 // Read Burst
philpem@0 290 if ((MB_RTY_I && (!(|data_length))) || (MB_ERR_I && (status2 == ST_WRITE)))
philpem@0 291 begin
philpem@0 292 status1 <= #UDLY ST_IDLE;
philpem@0 293 end
philpem@0 294 else
philpem@0 295 begin
philpem@0 296 case(status1)
philpem@0 297 ST_IDLE:
philpem@0 298 begin
philpem@0 299 if(fifo_wr)
philpem@0 300 fifo_wr <= #UDLY 1'b0;
philpem@0 301 if(MA_ACK_I)
philpem@0 302 begin
philpem@0 303 MA_CYC_O <= #UDLY 1'b0;
philpem@0 304 MA_STB_O <= #UDLY 1'b0;
philpem@0 305 MA_CTI_O <= #UDLY 3'h0;
philpem@0 306 end
philpem@0 307 if(reg_start | latch_start)
philpem@0 308 begin
philpem@0 309 if(fifo_empty)
philpem@0 310 begin
philpem@0 311 if(latch_start)
philpem@0 312 latch_start <= #UDLY 1'b0;
philpem@0 313 status1 <= #UDLY ST_READ;
philpem@0 314 MA_CYC_O <= #UDLY 1'b1;
philpem@0 315 MA_STB_O <= #UDLY 1'b1;
philpem@0 316 MA_ADR_O <= #UDLY reg_00_data;
philpem@0 317 case (reg_00_data[1:0])
philpem@0 318 2'b01: MA_SEL_O <= #UDLY {1'b0,M_SEL_O[3:1]};
philpem@0 319 2'b10: MA_SEL_O <= #UDLY {2'b00,M_SEL_O[3:2]};
philpem@0 320 2'b11: MA_SEL_O <= #UDLY {3'b00,M_SEL_O[3:3]};
philpem@0 321 default:
philpem@0 322 MA_SEL_O <= #UDLY M_SEL_O;
philpem@0 323 endcase
philpem@0 324 set_cti_a;
philpem@0 325 start_flag <= #UDLY 1'b1;
philpem@0 326 if(!(|data_length))
philpem@0 327 var_length1 <= #UDLY 1'b1;
philpem@0 328 else
philpem@0 329 var_length1 <= #UDLY 1'b0;
philpem@0 330 burst_size <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 331 burst_cnt <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 332 end
philpem@0 333 else
philpem@0 334 status1 <= #UDLY ST_RDFIFO;
philpem@0 335 end
philpem@0 336 else
philpem@0 337 status1 <= #UDLY ST_IDLE;
philpem@0 338 reg_interrupt1 <= #UDLY 1'b0;
philpem@0 339 end
philpem@0 340
philpem@0 341 ST_WAIT_WRITE_FINISH:
philpem@0 342 begin
philpem@0 343 fifo_wr <= #UDLY 1'b0;
philpem@0 344 if (status2 == ST_WRITE)
philpem@0 345 start_flag <= #UDLY 1'b0;
philpem@0 346 if(end_of_transfer)
philpem@0 347 begin
philpem@0 348 if(!reg_s_con)
philpem@0 349 MA_ADR_O <= #UDLY MA_ADR_O + incr_unit;
philpem@0 350 if (incr_unit == 3'b001)
philpem@0 351 MA_SEL_O <= #UDLY {MA_SEL_O[0], MA_SEL_O[3:1]};
philpem@0 352 else
philpem@0 353 if (incr_unit == 3'b010)
philpem@0 354 MA_SEL_O <= #UDLY {MA_SEL_O[1:0], MA_SEL_O[3:2]};
philpem@0 355
philpem@0 356 status1 <= #UDLY ST_RDADDR;
philpem@0 357 burst_cnt <= #UDLY burst_size;
philpem@0 358 end
philpem@0 359 else
philpem@0 360 begin
philpem@0 361 if(burst_completed)
philpem@0 362 status1 <= #UDLY ST_IDLE;
philpem@0 363 end
philpem@0 364 end
philpem@0 365
philpem@0 366 ST_RDFIFO:
philpem@0 367 begin
philpem@0 368 if(fifo_empty)
philpem@0 369 begin
philpem@0 370 status1 <= #UDLY ST_IDLE;
philpem@0 371 fifo_clear <= #UDLY 1'b0;
philpem@0 372 latch_start <= #UDLY 1'b1;
philpem@0 373 end
philpem@0 374 else
philpem@0 375 fifo_clear <= #UDLY !fifo_clear;
philpem@0 376 end
philpem@0 377
philpem@0 378 ST_RDADDR:
philpem@0 379 begin
philpem@0 380 MA_CYC_O <= #UDLY 1'b1;
philpem@0 381 MA_STB_O <= #UDLY 1'b1;
philpem@0 382 set_cti_a;
philpem@0 383 status1 <= #UDLY ST_READ;
philpem@0 384 end
philpem@0 385
philpem@0 386 ST_READ:
philpem@0 387 begin
philpem@0 388 write_fifo;
philpem@0 389 if(MA_ACK_I)
philpem@0 390 begin
philpem@0 391 if(start_flag)
philpem@0 392 begin
philpem@0 393 if(burst_cnt == 0)
philpem@0 394 begin
philpem@0 395 MA_CYC_O <= #UDLY 1'b0;
philpem@0 396 MA_STB_O <= #UDLY 1'b0;
philpem@0 397 MA_CTI_O <= #UDLY 3'h0;
philpem@0 398 status1 <= #UDLY ST_WAIT_WRITE_FINISH;
philpem@0 399 end
philpem@0 400 else
philpem@0 401 begin
philpem@0 402 if(burst_cnt == 1)
philpem@0 403 MA_CTI_O <= #UDLY 3'h7;
philpem@0 404 burst_cnt <= #UDLY burst_cnt - 1;
philpem@0 405 if(!reg_s_con)
philpem@0 406 MA_ADR_O <= #UDLY MA_ADR_O + incr_unit;
philpem@0 407 if (incr_unit == 3'b001)
philpem@0 408 MA_SEL_O <= #UDLY {MA_SEL_O[0], MA_SEL_O[3:1]};
philpem@0 409 else
philpem@0 410 if (incr_unit == 3'b010)
philpem@0 411 MA_SEL_O <= #UDLY {MA_SEL_O[1:0], MA_SEL_O[3:2]};
philpem@0 412 end
philpem@0 413 end
philpem@0 414 else
philpem@0 415 begin
philpem@0 416 if(burst_cnt == 0)
philpem@0 417 begin
philpem@0 418 MA_CYC_O <= #UDLY 1'b0;
philpem@0 419 MA_STB_O <= #UDLY 1'b0;
philpem@0 420 MA_CTI_O <= #UDLY 3'h0;
philpem@0 421 status1 <= #UDLY ST_WAIT_WRITE_FINISH;
philpem@0 422 end
philpem@0 423 else
philpem@0 424 begin
philpem@0 425 if(burst_cnt == 1)
philpem@0 426 MA_CTI_O <= #UDLY 3'h7;
philpem@0 427 if(!reg_s_con)
philpem@0 428 MA_ADR_O <= #UDLY MA_ADR_O + incr_unit;
philpem@0 429 if (incr_unit == 3'b001)
philpem@0 430 MA_SEL_O <= #UDLY {MA_SEL_O[0], MA_SEL_O[3:1]};
philpem@0 431 else
philpem@0 432 if (incr_unit == 3'b010)
philpem@0 433 MA_SEL_O <= #UDLY {MA_SEL_O[1:0], MA_SEL_O[3:2]};
philpem@0 434 burst_cnt <= #UDLY burst_cnt - 1;
philpem@0 435 end
philpem@0 436 end
philpem@0 437 end
philpem@0 438 else if(MA_RTY_I)
philpem@0 439 begin
philpem@0 440 if(var_length1)
philpem@0 441 begin
philpem@0 442 MA_CYC_O <= #UDLY 1'b0;
philpem@0 443 MA_STB_O <= #UDLY 1'b0;
philpem@0 444 MA_CTI_O <= #UDLY 3'h0;
philpem@0 445 status1 <= #UDLY ST_IDLE;
philpem@0 446 reg_status1 <= #UDLY 1'b0;
philpem@0 447 reg_interrupt1 <= #UDLY 1'b1;
philpem@0 448 start_flag <= #UDLY 1'b0;
philpem@0 449 end
philpem@0 450 end
philpem@0 451 else if(MA_ERR_I)
philpem@0 452 begin
philpem@0 453 MA_CYC_O <= #UDLY 1'b0;
philpem@0 454 MA_STB_O <= #UDLY 1'b0;
philpem@0 455 MA_CTI_O <= #UDLY 3'h0;
philpem@0 456 status1 <= #UDLY ST_IDLE;
philpem@0 457 reg_status1 <= #UDLY 1'b1;
philpem@0 458 reg_interrupt1 <= #UDLY 1'b1;
philpem@0 459 start_flag <= #UDLY 1'b0;
philpem@0 460 end
philpem@0 461 end
philpem@0 462
philpem@0 463 default:
philpem@0 464 begin
philpem@0 465 status1 <= #UDLY ST_IDLE;
philpem@0 466 var_length1 <= #UDLY 1'b0;
philpem@0 467 MA_ADR_O <= #UDLY 32'h0;
philpem@0 468 MA_SEL_O <= #UDLY 4'b1111;
philpem@0 469 MA_CYC_O <= #UDLY 1'b0;
philpem@0 470 MA_CTI_O <= #UDLY 3'h0;
philpem@0 471 MA_STB_O <= #UDLY 1'b0;
philpem@0 472 reg_status1 <= #UDLY 1'b0;
philpem@0 473 reg_interrupt1 <= #UDLY 1'b0;
philpem@0 474 start_flag <= #UDLY 1'b0;
philpem@0 475 burst_size <= #UDLY 5'h0;
philpem@0 476 burst_cnt <= #UDLY 5'h0;
philpem@0 477 fifo_clear <= #UDLY 1'b0;
philpem@0 478 latch_start <= #UDLY 1'b0;
philpem@0 479 fifo_wr <= #UDLY 1'b0;
philpem@0 480 end
philpem@0 481 endcase
philpem@0 482 end
philpem@0 483 // Write Burst
philpem@0 484 if ((MA_RTY_I && (!(|data_length))) || (MA_ERR_I && (status1 == ST_READ)))
philpem@0 485 begin
philpem@0 486 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 487 donot_start_again <= #UDLY 1'b1;
philpem@0 488 end
philpem@0 489 else
philpem@0 490 begin
philpem@0 491 case(status2)
philpem@0 492 ST_WRITE_IDLE:
philpem@0 493 begin
philpem@0 494 if(reg_start)
philpem@0 495 begin
philpem@0 496 MB_ADR_O <= #UDLY reg_04_data;
philpem@0 497 case (reg_04_data[1:0])
philpem@0 498 2'b01: MB_SEL_O <= #UDLY {1'b0,M_SEL_O[3:1]};
philpem@0 499 2'b10: MB_SEL_O <= #UDLY {2'b00,M_SEL_O[3:2]};
philpem@0 500 2'b11: MB_SEL_O <= #UDLY {3'b00,M_SEL_O[3:3]};
philpem@0 501 default:
philpem@0 502 MB_SEL_O <= #UDLY M_SEL_O;
philpem@0 503 endcase
philpem@0 504 if(!(|data_length))
philpem@0 505 var_length2 <= #UDLY 1'b1;
philpem@0 506 else
philpem@0 507 var_length2 <= #UDLY 1'b0;
philpem@0 508 burst_size2 <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 509 burst_cnt2 <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 510 if(!fifo_empty)
philpem@0 511 status2 <= #UDLY ST_FIFO_EMPTY;
philpem@0 512 else
philpem@0 513 donot_start_again <= #UDLY 1'b0;
philpem@0 514 end
philpem@0 515 if(fifo_empty)
philpem@0 516 begin
philpem@0 517 if(MB_ACK_I)
philpem@0 518 begin
philpem@0 519 MB_CYC_O <= #UDLY 1'b0;
philpem@0 520 MB_STB_O <= #UDLY 1'b0;
philpem@0 521 MB_CTI_O <= #UDLY 3'h0;
philpem@0 522 fifo_rd <= #UDLY 1'b0;
philpem@0 523 end
philpem@0 524 burst_cnt2 <= #UDLY 5'h0;
philpem@0 525 end
philpem@0 526 else
philpem@0 527 begin
philpem@0 528 if(donot_start_again)
philpem@0 529 begin
philpem@0 530 if(MB_ACK_I)
philpem@0 531 begin
philpem@0 532 if(!reg_d_con)
philpem@0 533 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 534 if (incr_unit == 3'b001)
philpem@0 535 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 536 else
philpem@0 537 if (incr_unit == 3'b010)
philpem@0 538 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 539 end
philpem@0 540 end
philpem@0 541 end
philpem@0 542
philpem@0 543 if(!fifo_empty && !donot_start_again)
philpem@0 544 begin
philpem@0 545 if(start_flag)
philpem@0 546 begin
philpem@0 547 set_cti_b;
philpem@0 548 status2 <= #UDLY ST_WRITE_WAIT;
philpem@0 549 read_fifo;
philpem@0 550 burst_cnt2 <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 551 end
philpem@0 552 else
philpem@0 553 begin
philpem@0 554 if(!reg_d_con)
philpem@0 555 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 556 if (incr_unit == 3'b001)
philpem@0 557 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 558 else
philpem@0 559 if (incr_unit == 3'b010)
philpem@0 560 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 561 status2 <= #UDLY ST_WRADDR;
philpem@0 562 read_fifo;
philpem@0 563 burst_cnt2 <= #UDLY reg_bt1 ? (reg_bt0 ? 5'h1f : 5'hf) : (reg_bt0 ? 5'h7 : 5'h3);
philpem@0 564 end
philpem@0 565 end
philpem@0 566 end_of_transfer <= #UDLY 1'b0;
philpem@0 567 burst_completed <= #UDLY 1'b0;
philpem@0 568 reg_interrupt2 <= #UDLY 1'b0;
philpem@0 569 end
philpem@0 570
philpem@0 571 ST_FIFO_EMPTY:
philpem@0 572 begin
philpem@0 573 if(fifo_empty)
philpem@0 574 begin
philpem@0 575 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 576 donot_start_again <= #UDLY 1'b0;
philpem@0 577 end
philpem@0 578 end
philpem@0 579
philpem@0 580 ST_WRADDR:
philpem@0 581 begin
philpem@0 582 burst_cnt2 <= #UDLY burst_size2;
philpem@0 583 MB_CYC_O <= #UDLY 1'b1;
philpem@0 584 MB_STB_O <= #UDLY 1'b1;
philpem@0 585
philpem@0 586 if (fifo_aempty && (burst_size2 > 5'h2))
philpem@0 587 begin
philpem@0 588 MB_CTI_O <= #UDLY 3'b000;
philpem@0 589 status2 <= #UDLY ST_FIFO_AEMPTY;
philpem@0 590 fifo_rd <= #UDLY 1'b0;
philpem@0 591 end
philpem@0 592 else
philpem@0 593 begin
philpem@0 594 set_cti_b;
philpem@0 595 status2 <= #UDLY ST_WRITE;
philpem@0 596 end
philpem@0 597 end
philpem@0 598
philpem@0 599 ST_WRITE_WAIT:
philpem@0 600 begin
philpem@0 601 MB_CYC_O <= #UDLY 1'b1;
philpem@0 602 MB_STB_O <= #UDLY 1'b1;
philpem@0 603
philpem@0 604 if (fifo_aempty && (burst_size2 > 5'h2))
philpem@0 605 begin
philpem@0 606 MB_CTI_O <= #UDLY 3'b000;
philpem@0 607 status2 <= #UDLY ST_FIFO_AEMPTY;
philpem@0 608 fifo_rd <= #UDLY 1'b0;
philpem@0 609 end
philpem@0 610 else
philpem@0 611 begin
philpem@0 612 set_cti_b;
philpem@0 613 status2 <= #UDLY ST_WRITE;
philpem@0 614 end
philpem@0 615 end
philpem@0 616
philpem@0 617 ST_FIFO_AEMPTY:
philpem@0 618 begin
philpem@0 619 if (MB_ACK_I)
philpem@0 620 begin
philpem@0 621 MB_CYC_O <= #UDLY 1'b0;
philpem@0 622 MB_STB_O <= #UDLY 1'b0;
philpem@0 623
philpem@0 624 burst_cnt2 <= #UDLY burst_cnt2 - 1;
philpem@0 625
philpem@0 626 if (!reg_d_con)
philpem@0 627 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 628
philpem@0 629 if (incr_unit == 3'b001)
philpem@0 630 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 631 else
philpem@0 632 if (incr_unit == 3'b010)
philpem@0 633 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 634 end
philpem@0 635
philpem@0 636 if (!MB_CYC_O && !fifo_aempty)
philpem@0 637 begin
philpem@0 638 status2 <= #UDLY ST_FIFO_RESUME;
philpem@0 639 read_fifo;
philpem@0 640 end
philpem@0 641 end
philpem@0 642
philpem@0 643 ST_FIFO_RESUME:
philpem@0 644 begin
philpem@0 645 MB_CYC_O <= #UDLY 1'b1;
philpem@0 646 MB_STB_O <= #UDLY 1'b1;
philpem@0 647
philpem@0 648 if (fifo_aempty && (burst_cnt2 > 5'h2))
philpem@0 649 begin
philpem@0 650 MB_CTI_O <= #UDLY 3'b000;
philpem@0 651 status2 <= #UDLY ST_FIFO_AEMPTY;
philpem@0 652 fifo_rd <= #UDLY 1'b0;
philpem@0 653 end
philpem@0 654 else
philpem@0 655 begin
philpem@0 656 set_cti_b;
philpem@0 657 status2 <= #UDLY ST_WRITE;
philpem@0 658 end
philpem@0 659 end
philpem@0 660
philpem@0 661 ST_WRITE:
philpem@0 662 begin
philpem@0 663 if (MB_ACK_I)
philpem@0 664 begin
philpem@0 665 if(var_length2)
philpem@0 666 begin
philpem@0 667 if(burst_cnt2 == 0)
philpem@0 668 begin
philpem@0 669 MB_CYC_O <= #UDLY 1'b0;
philpem@0 670 MB_STB_O <= #UDLY 1'b0;
philpem@0 671 MB_CTI_O <= #UDLY 3'h0;
philpem@0 672 end_of_transfer <= #UDLY 1'b1;
philpem@0 673 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 674 fifo_rd <= #UDLY 1'b0;
philpem@0 675 burst_cnt2 <= #UDLY burst_size2;
philpem@0 676 end
philpem@0 677 else
philpem@0 678 begin
philpem@0 679 if(burst_cnt2 == 1)
philpem@0 680 MB_CTI_O <= #UDLY 3'h7;
philpem@0 681 else
philpem@0 682 set_cti_b;
philpem@0 683 if(!reg_d_con)
philpem@0 684 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 685 if (incr_unit == 3'b001)
philpem@0 686 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 687 else
philpem@0 688 if (incr_unit == 3'b010)
philpem@0 689 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 690 read_fifo;
philpem@0 691 burst_cnt2 <= #UDLY burst_cnt2 - 1;
philpem@0 692 end
philpem@0 693 end
philpem@0 694 else
philpem@0 695 begin
philpem@0 696 if(burst_cnt2 == 0)
philpem@0 697 begin
philpem@0 698 MB_CYC_O <= #UDLY 1'b0;
philpem@0 699 MB_STB_O <= #UDLY 1'b0;
philpem@0 700 MB_CTI_O <= #UDLY 3'h0;
philpem@0 701 reg_cntlg_burst <= #UDLY 1'b1;
philpem@0 702 status2 <= #UDLY ST_CNTLNGTH;
philpem@0 703 fifo_rd <= #UDLY 1'b0;
philpem@0 704 burst_cnt2 <= #UDLY burst_size2;
philpem@0 705 end
philpem@0 706 else
philpem@0 707 begin
philpem@0 708 if ((fifo_aempty && (burst_cnt2 > 5'h2)) || (burst_cnt2 == 5'h1))
philpem@0 709 MB_CTI_O <= #UDLY 3'h7;
philpem@0 710 else
philpem@0 711 set_cti_b;
philpem@0 712
philpem@0 713 burst_cnt2 <= #UDLY burst_cnt2 - 1;
philpem@0 714
philpem@0 715 if(!reg_d_con)
philpem@0 716 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 717
philpem@0 718 if (incr_unit == 3'b001)
philpem@0 719 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 720 else
philpem@0 721 if (incr_unit == 3'b010)
philpem@0 722 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 723
philpem@0 724 if (fifo_aempty && (burst_cnt2 > 5'h2))
philpem@0 725 begin
philpem@0 726 status2 <= #UDLY ST_FIFO_AEMPTY;
philpem@0 727 fifo_rd <= 1'b0;
philpem@0 728 end
philpem@0 729 else
philpem@0 730 read_fifo;
philpem@0 731 end
philpem@0 732 end
philpem@0 733 end
philpem@0 734
philpem@0 735 else if(MB_RTY_I)
philpem@0 736 begin
philpem@0 737 if(var_length2)
philpem@0 738 begin
philpem@0 739 MB_CYC_O <= #UDLY 1'b0;
philpem@0 740 MB_STB_O <= #UDLY 1'b0;
philpem@0 741 MB_CTI_O <= #UDLY 3'h0;
philpem@0 742 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 743 reg_status2 <= #UDLY 1'b0;
philpem@0 744 reg_interrupt2 <= #UDLY 1'b1;
philpem@0 745 var_length2 <= #UDLY 1'b0;
philpem@0 746 donot_start_again <= #UDLY 1'b1;
philpem@0 747 fifo_rd <= #UDLY 1'b0;
philpem@0 748 end
philpem@0 749 end // if (MB_RTY_I)
philpem@0 750
philpem@0 751 else if(MB_ERR_I)
philpem@0 752 begin
philpem@0 753 MB_CYC_O <= #UDLY 1'b0;
philpem@0 754 MB_STB_O <= #UDLY 1'b0;
philpem@0 755 MB_CTI_O <= #UDLY 3'h0;
philpem@0 756 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 757 reg_status2 <= #UDLY 1'b1;
philpem@0 758 reg_interrupt2 <= #UDLY 1'b1;
philpem@0 759 donot_start_again <= #UDLY 1'b1;
philpem@0 760 fifo_rd <= #UDLY 1'b0;
philpem@0 761 end // if (MB_ERR_I)
philpem@0 762
philpem@0 763 end
philpem@0 764
philpem@0 765 ST_CNTLNGTH:
philpem@0 766 begin
philpem@0 767 reg_cntlg_burst <= #UDLY 1'b0;
philpem@0 768 status2 <= #UDLY ST_JUSTICE;
philpem@0 769 end
philpem@0 770
philpem@0 771 ST_JUSTICE:
philpem@0 772 begin
philpem@0 773 if(!(|data_length))
philpem@0 774 begin
philpem@0 775 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 776 reg_status2 <= #UDLY 1'b0;
philpem@0 777 reg_interrupt2 <= #UDLY 1'b1;
philpem@0 778 burst_completed <= #UDLY 1'b1;
philpem@0 779 end
philpem@0 780 else
philpem@0 781 begin
philpem@0 782 end_of_transfer <= #UDLY 1'b1;
philpem@0 783 status2 <= ST_WRITE_IDLE;
philpem@0 784 end
philpem@0 785 end
philpem@0 786
philpem@0 787 default:
philpem@0 788 begin
philpem@0 789 status2 <= #UDLY ST_WRITE_IDLE;
philpem@0 790 MB_ADR_O <= #UDLY 32'h0;
philpem@0 791 MB_SEL_O <= #UDLY 4'b1111;
philpem@0 792 MB_CYC_O <= #UDLY 1'b0;
philpem@0 793 MB_CTI_O <= #UDLY 3'h0;
philpem@0 794 MB_STB_O <= #UDLY 1'b0;
philpem@0 795 reg_status2 <= #UDLY 1'b0;
philpem@0 796 reg_interrupt2 <= #UDLY 1'b0;
philpem@0 797 reg_cntlg_burst <= #UDLY 1'b0;
philpem@0 798 burst_size2 <= #UDLY 5'h0;
philpem@0 799 burst_cnt2 <= #UDLY 5'h0;
philpem@0 800 fifo_rd <= #UDLY 1'b0;
philpem@0 801 end_of_transfer <= #UDLY 1'b0;
philpem@0 802 var_length2 <= #UDLY 1'b0;
philpem@0 803 burst_completed <= #UDLY 1'b0;
philpem@0 804 donot_start_again <= #UDLY 1'b0;
philpem@0 805 end
philpem@0 806 endcase
philpem@0 807 end
philpem@0 808 end
philpem@0 809 else begin
philpem@0 810 // Read/Write Normal
philpem@0 811 case(status)
philpem@0 812
philpem@0 813 ST_IDLE1:
philpem@0 814 begin
philpem@0 815 if(reg_start | latch_start)
philpem@0 816 begin
philpem@0 817 if(fifo_empty)
philpem@0 818 begin
philpem@0 819 if(latch_start)
philpem@0 820 latch_start <= #UDLY 1'b0;
philpem@0 821 status <= #UDLY ST_READ1;
philpem@0 822 MA_CYC_O <= #UDLY 1'b1;
philpem@0 823 MA_STB_O <= #UDLY 1'b1;
philpem@0 824 MA_ADR_O <= #UDLY reg_00_data;
philpem@0 825 case (reg_00_data[1:0])
philpem@0 826 2'b01: MA_SEL_O <= #UDLY {1'b0,M_SEL_O[3:1]};
philpem@0 827 2'b10: MA_SEL_O <= #UDLY {2'b00,M_SEL_O[3:2]};
philpem@0 828 2'b11: MA_SEL_O <= #UDLY {3'b00,M_SEL_O[3:3]};
philpem@0 829 default:
philpem@0 830 MA_SEL_O <= #UDLY M_SEL_O;
philpem@0 831 endcase
philpem@0 832 MB_ADR_O <= #UDLY reg_04_data;
philpem@0 833 case (reg_04_data[1:0])
philpem@0 834 2'b01: MB_SEL_O <= #UDLY {1'b0,M_SEL_O[3:1]};
philpem@0 835 2'b10: MB_SEL_O <= #UDLY {2'b00,M_SEL_O[3:2]};
philpem@0 836 2'b11: MB_SEL_O <= #UDLY {3'b00,M_SEL_O[3:3]};
philpem@0 837 default:
philpem@0 838 MB_SEL_O <= #UDLY M_SEL_O;
philpem@0 839 endcase
philpem@0 840 set_cti_a;
philpem@0 841 start_flag <= #UDLY 1'b1;
philpem@0 842 if(!(|data_length))
philpem@0 843 var_length <= #UDLY 1'b1;
philpem@0 844 else
philpem@0 845 var_length <= #UDLY 1'b0;
philpem@0 846 burst_size <= #UDLY 5'h0;
philpem@0 847 burst_cnt <= #UDLY 5'h0;
philpem@0 848 end
philpem@0 849 else
philpem@0 850 begin
philpem@0 851 status <= #UDLY ST_RDFIFO1;
philpem@0 852 end
philpem@0 853 end
philpem@0 854 else
philpem@0 855 begin
philpem@0 856 status <= #UDLY ST_IDLE1;
philpem@0 857 end
philpem@0 858 reg_interrupt_normal <= #UDLY 1'b0;
philpem@0 859 end
philpem@0 860 ST_RDFIFO1:
philpem@0 861 begin
philpem@0 862 if(fifo_empty)
philpem@0 863 begin
philpem@0 864 status <= #UDLY ST_IDLE1;
philpem@0 865 fifo_clear <= #UDLY 1'b0;
philpem@0 866 latch_start <= #UDLY 1'b1;
philpem@0 867 end
philpem@0 868 else
philpem@0 869 fifo_clear <= #UDLY !fifo_clear;
philpem@0 870 end
philpem@0 871
philpem@0 872 ST_RDADDR1:
philpem@0 873 begin
philpem@0 874 MA_CYC_O <= #UDLY 1'b1;
philpem@0 875 MA_STB_O <= #UDLY 1'b1;
philpem@0 876 set_cti_a;
philpem@0 877 status <= #UDLY ST_READ1;
philpem@0 878 direct_data <= #UDLY 1'b1;
philpem@0 879 end
philpem@0 880
philpem@0 881 ST_READ1:
philpem@0 882 begin
philpem@0 883 if(!start_flag)
philpem@0 884 write_fifo;
philpem@0 885 if(MA_ACK_I)
philpem@0 886 begin
philpem@0 887 if(start_flag)
philpem@0 888 begin
philpem@0 889 MA_CYC_O <= #UDLY 1'b0;
philpem@0 890 MA_STB_O <= #UDLY 1'b0;
philpem@0 891 MA_CTI_O <= #UDLY 3'h0;
philpem@0 892 MB_CYC_O <= #UDLY 1'b1;
philpem@0 893 MB_STB_O <= #UDLY 1'b1;
philpem@0 894 set_cti_b;
philpem@0 895 status <= #UDLY ST_WRITE1;
philpem@0 896 start_flag <= #UDLY 1'b0;
philpem@0 897 burst_cnt <= #UDLY burst_size;
philpem@0 898 end
philpem@0 899 else
philpem@0 900 begin
philpem@0 901 MA_CYC_O <= #UDLY 1'b0;
philpem@0 902 MA_STB_O <= #UDLY 1'b0;
philpem@0 903 MA_CTI_O <= #UDLY 3'h0;
philpem@0 904 if(!reg_d_con)
philpem@0 905 begin
philpem@0 906 MB_ADR_O <= #UDLY MB_ADR_O + incr_unit;
philpem@0 907 if (incr_unit == 3'b001)
philpem@0 908 MB_SEL_O <= #UDLY {MB_SEL_O[0], MB_SEL_O[3:1]};
philpem@0 909 else
philpem@0 910 if (incr_unit == 3'b010)
philpem@0 911 MB_SEL_O <= #UDLY {MB_SEL_O[1:0], MB_SEL_O[3:2]};
philpem@0 912 end
philpem@0 913 status <= #UDLY ST_WRADDR1;
philpem@0 914 burst_cnt <= #UDLY burst_size;
philpem@0 915 end
philpem@0 916 end
philpem@0 917 else if(MA_RTY_I)
philpem@0 918 begin
philpem@0 919 if(var_length)
philpem@0 920 begin
philpem@0 921 MA_CYC_O <= #UDLY 1'b0;
philpem@0 922 MA_STB_O <= #UDLY 1'b0;
philpem@0 923 MA_CTI_O <= #UDLY 3'h0;
philpem@0 924 status <= #UDLY ST_IDLE1;
philpem@0 925 reg_status_normal <= #UDLY 1'b0;
philpem@0 926 reg_interrupt_normal <= #UDLY 1'b1;
philpem@0 927 end
philpem@0 928 end
philpem@0 929 else if(MA_ERR_I)
philpem@0 930 begin
philpem@0 931 MA_CYC_O <= #UDLY 1'b0;
philpem@0 932 MA_STB_O <= #UDLY 1'b0;
philpem@0 933 MA_CTI_O <= #UDLY 3'h0;
philpem@0 934 status <= #UDLY ST_IDLE1;
philpem@0 935 reg_status_normal <= #UDLY 1'b1;
philpem@0 936 reg_interrupt_normal <= #UDLY 1'b1;
philpem@0 937 end
philpem@0 938 end
philpem@0 939
philpem@0 940 ST_WRADDR1:
philpem@0 941 begin
philpem@0 942 fifo_wr <= #UDLY 1'b0;
philpem@0 943 MB_CYC_O <= #UDLY 1'b1;
philpem@0 944 MB_STB_O <= #UDLY 1'b1;
philpem@0 945 burst_cnt <= #UDLY burst_size;
philpem@0 946 set_cti_b;
philpem@0 947 status <= #UDLY ST_WRITE1;
philpem@0 948 read_fifo;
philpem@0 949 end
philpem@0 950
philpem@0 951 ST_WRITE1:
philpem@0 952 begin
philpem@0 953 if(fifo_wr)
philpem@0 954 fifo_wr <= #UDLY 1'b0;
philpem@0 955 if(MB_ACK_I)
philpem@0 956 begin
philpem@0 957 direct_data <= #UDLY 1'b0;
philpem@0 958 if(var_length)
philpem@0 959 begin
philpem@0 960 MB_CYC_O <= #UDLY 1'b0;
philpem@0 961 MB_STB_O <= #UDLY 1'b0;
philpem@0 962 MB_CTI_O <= #UDLY 3'h0;
philpem@0 963 if(!reg_s_con)
philpem@0 964 begin
philpem@0 965 MA_ADR_O <= #UDLY MA_ADR_O + incr_unit;
philpem@0 966 if (incr_unit == 3'b001)
philpem@0 967 MA_SEL_O <= #UDLY {MA_SEL_O[0], MA_SEL_O[3:1]};
philpem@0 968 else
philpem@0 969 if (incr_unit == 3'b010)
philpem@0 970 MA_SEL_O <= #UDLY {MA_SEL_O[1:0], MA_SEL_O[3:2]};
philpem@0 971 end
philpem@0 972 status <= #UDLY ST_RDADDR1;
philpem@0 973 fifo_rd <= #UDLY 1'b0;
philpem@0 974 burst_cnt <= #UDLY burst_size;
philpem@0 975 end
philpem@0 976 else
philpem@0 977 begin
philpem@0 978 MB_CYC_O <= #UDLY 1'b0;
philpem@0 979 MB_STB_O <= #UDLY 1'b0;
philpem@0 980 MB_CTI_O <= #UDLY 3'h0;
philpem@0 981 reg_cntlg_normal <= #UDLY 1'b1;
philpem@0 982 status <= #UDLY ST_CNTLNGTH1;
philpem@0 983 fifo_rd <= #UDLY 1'b0;
philpem@0 984 burst_cnt <= #UDLY burst_size;
philpem@0 985 end
philpem@0 986 end
philpem@0 987 else if(MB_RTY_I)
philpem@0 988 begin
philpem@0 989 if(var_length)
philpem@0 990 begin
philpem@0 991 MB_CYC_O <= #UDLY 1'b0;
philpem@0 992 MB_STB_O <= #UDLY 1'b0;
philpem@0 993 MB_CTI_O <= #UDLY 3'h0;
philpem@0 994 status <= #UDLY ST_IDLE1;
philpem@0 995 reg_status_normal <= #UDLY 1'b0;
philpem@0 996 reg_interrupt_normal <= #UDLY 1'b1;
philpem@0 997 var_length <= #UDLY 1'b0;
philpem@0 998 fifo_rd <= #UDLY 1'b0;
philpem@0 999 end
philpem@0 1000 end
philpem@0 1001 else if(MB_ERR_I)
philpem@0 1002 begin
philpem@0 1003 MB_CYC_O <= #UDLY 1'b0;
philpem@0 1004 MB_STB_O <= #UDLY 1'b0;
philpem@0 1005 MB_CTI_O <= #UDLY 3'h0;
philpem@0 1006 status <= #UDLY ST_IDLE1;
philpem@0 1007 reg_status_normal <= #UDLY 1'b1;
philpem@0 1008 reg_interrupt_normal <= #UDLY 1'b1;
philpem@0 1009 fifo_rd <= #UDLY 1'b0;
philpem@0 1010 end
philpem@0 1011 end
philpem@0 1012
philpem@0 1013 ST_CNTLNGTH1:
philpem@0 1014 begin
philpem@0 1015 reg_cntlg_normal <= #UDLY 1'b0;
philpem@0 1016 status <= #UDLY ST_JUSTICE1;
philpem@0 1017 end
philpem@0 1018
philpem@0 1019 ST_JUSTICE1:
philpem@0 1020 begin
philpem@0 1021 if(!(|data_length))
philpem@0 1022 begin
philpem@0 1023 status <= #UDLY ST_IDLE1;
philpem@0 1024 reg_status_normal <= #UDLY 1'b0;
philpem@0 1025 reg_interrupt_normal <= #UDLY 1'b1;
philpem@0 1026 end
philpem@0 1027 else
philpem@0 1028 begin
philpem@0 1029 if(!reg_s_con)
philpem@0 1030 begin
philpem@0 1031 MA_ADR_O <= #UDLY MA_ADR_O + incr_unit;
philpem@0 1032 if (incr_unit == 3'b001)
philpem@0 1033 MA_SEL_O <= #UDLY {MA_SEL_O[0], MA_SEL_O[3:1]};
philpem@0 1034 else
philpem@0 1035 if (incr_unit == 3'b010)
philpem@0 1036 MA_SEL_O <= #UDLY {MA_SEL_O[1:0], MA_SEL_O[3:2]};
philpem@0 1037 end
philpem@0 1038 status <= #UDLY ST_RDADDR1;
philpem@0 1039 end
philpem@0 1040 end
philpem@0 1041
philpem@0 1042 default:
philpem@0 1043 begin
philpem@0 1044 status <= #UDLY ST_IDLE1;
philpem@0 1045 var_length <= #UDLY 1'b0;
philpem@0 1046 MA_CYC_O <= #UDLY 1'b0;
philpem@0 1047 MA_CTI_O <= #UDLY 3'h0;
philpem@0 1048 MB_CYC_O <= #UDLY 1'b0;
philpem@0 1049 MB_CTI_O <= #UDLY 3'h0;
philpem@0 1050 MA_STB_O <= #UDLY 1'b0;
philpem@0 1051 MB_STB_O <= #UDLY 1'b0;
philpem@0 1052 reg_status_normal <= #UDLY 1'b0;
philpem@0 1053 reg_interrupt_normal <= #UDLY 1'b0;
philpem@0 1054 reg_cntlg_normal <= #UDLY 1'b0;
philpem@0 1055 burst_size <= #UDLY 3'h0;
philpem@0 1056 burst_cnt <= #UDLY 3'h0;
philpem@0 1057 fifo_wr <= #UDLY 1'b0;
philpem@0 1058 fifo_rd <= #UDLY 1'b0;
philpem@0 1059 fifo_clear <= #UDLY 1'b0;
philpem@0 1060 latch_start <= #UDLY 1'b0;
philpem@0 1061 direct_data <= #UDLY 1'b0;
philpem@0 1062 end
philpem@0 1063 endcase
philpem@0 1064 end
philpem@0 1065 end
philpem@0 1066
philpem@0 1067 //Task for generating write enable to the FIFO
philpem@0 1068 task write_fifo;
philpem@0 1069 begin
philpem@0 1070 if(MA_ACK_I)
philpem@0 1071 begin
philpem@0 1072 fifo_wr <= #UDLY 1'b1;
philpem@0 1073 fifo_din <= #UDLY MA_DAT_I;
philpem@0 1074 end
philpem@0 1075 else
philpem@0 1076 begin
philpem@0 1077 fifo_wr <= #UDLY 1'b0;
philpem@0 1078 end
philpem@0 1079 end
philpem@0 1080 endtask
philpem@0 1081
philpem@0 1082 //Task for generating read enable signal to the FIFO
philpem@0 1083 task read_fifo;
philpem@0 1084 begin
philpem@0 1085 fifo_rd <= #UDLY 1'b1;
philpem@0 1086 end
philpem@0 1087 endtask
philpem@0 1088
philpem@0 1089 //Task for setting wishbone CTI signal for read
philpem@0 1090 //master port depending upon whether request is for burst
philpem@0 1091 //transfer or classic cycle.
philpem@0 1092 task set_cti_a;
philpem@0 1093 begin
philpem@0 1094 if(reg_bt2)
philpem@0 1095 begin
philpem@0 1096 if(reg_s_con)
philpem@0 1097 MA_CTI_O <= #UDLY 3'b001;
philpem@0 1098 else
philpem@0 1099 MA_CTI_O <= #UDLY 3'b010;
philpem@0 1100 end
philpem@0 1101 else
philpem@0 1102 MA_CTI_O <= #UDLY 3'b000;
philpem@0 1103 end
philpem@0 1104 endtask
philpem@0 1105
philpem@0 1106 //Task for setting wishbone CTI signal for write
philpem@0 1107 //master port depending upon whether request is for burst
philpem@0 1108 //transfer or classic cycle.
philpem@0 1109 task set_cti_b;
philpem@0 1110 begin
philpem@0 1111 if(reg_bt2) begin
philpem@0 1112 if(reg_d_con)
philpem@0 1113 MB_CTI_O <= #UDLY 3'b001;
philpem@0 1114 else
philpem@0 1115 MB_CTI_O <= #UDLY 3'b010;
philpem@0 1116 end else
philpem@0 1117 MB_CTI_O <= #UDLY 3'b000;
philpem@0 1118 end
philpem@0 1119 endtask
philpem@0 1120
philpem@0 1121 //RdEn
philpem@0 1122 reg fifo_rd_dly;
philpem@0 1123 always @(posedge CLK_I or posedge RST_I)
philpem@0 1124 if(RST_I)
philpem@0 1125 fifo_rd_dly <= #UDLY 1'b0;
philpem@0 1126 else
philpem@0 1127 fifo_rd_dly <= #UDLY fifo_rd;
philpem@0 1128
philpem@0 1129 wire RdEn = fifo_rd & (!fifo_rd_dly | (reg_bt2 ? (burst_cnt2[5:0] != 5'b00000) : (burst_cnt[5:0] != 5'b00000)) & MB_ACK_I) | fifo_clear;
philpem@0 1130
philpem@0 1131 generate
philpem@0 1132 if (lat_family == "SC" || lat_family == "SCM") begin
philpem@0 1133
philpem@0 1134 pmi_fifo_dc #(.pmi_data_width_w(32),
philpem@0 1135 .pmi_data_width_r(32),
philpem@0 1136 .pmi_data_depth_w(32),
philpem@0 1137 .pmi_data_depth_r(32),
philpem@0 1138 .pmi_full_flag(32),
philpem@0 1139 .pmi_empty_flag(0),
philpem@0 1140 .pmi_almost_full_flag(28),
philpem@0 1141 .pmi_almost_empty_flag(4),
philpem@0 1142 .pmi_regmode("noreg"),
philpem@0 1143 .pmi_family(`LATTICE_FAMILY),
philpem@0 1144 .module_type("pmi_fifo_dc"),
philpem@0 1145 .pmi_implementation(FIFO_IMPLEMENTATION))
philpem@0 1146 dma_fifo_dc (
philpem@0 1147 .Data(fifo_din),
philpem@0 1148 .WrClock(CLK_I),
philpem@0 1149 .RdClock(CLK_I),
philpem@0 1150 .WrEn (fifo_wr),
philpem@0 1151 .RdEn (RdEn),
philpem@0 1152 .Reset (RST_I),
philpem@0 1153 .RPReset(RST_I),
philpem@0 1154 .Q (fifo_dout),
philpem@0 1155 .Empty (fifo_empty),
philpem@0 1156 .Full (),
philpem@0 1157 .AlmostEmpty (),
philpem@0 1158 .AlmostFull ());
philpem@0 1159
philpem@0 1160
philpem@0 1161
philpem@0 1162 end else begin
philpem@0 1163 pmi_fifo #(.pmi_data_width(32),
philpem@0 1164 .pmi_data_depth(32),
philpem@0 1165 .pmi_full_flag(32),
philpem@0 1166 .pmi_empty_flag(0),
philpem@0 1167 .pmi_almost_full_flag(28),
philpem@0 1168 .pmi_almost_empty_flag(1),
philpem@0 1169 .pmi_regmode("noreg"),
philpem@0 1170 .pmi_family(`LATTICE_FAMILY),
philpem@0 1171 .module_type("pmi_fifo"),
philpem@0 1172 .pmi_implementation(FIFO_IMPLEMENTATION))
philpem@0 1173 dma_fifo (.Data (fifo_din),
philpem@0 1174 .Clock (CLK_I),
philpem@0 1175 .WrEn (fifo_wr),
philpem@0 1176 .RdEn (RdEn),
philpem@0 1177 .Reset (RST_I),
philpem@0 1178 .Q (fifo_dout),
philpem@0 1179 .Empty (fifo_empty),
philpem@0 1180 .Full (),
philpem@0 1181 .AlmostEmpty (fifo_aempty),
philpem@0 1182 .AlmostFull ());
philpem@0 1183 end
philpem@0 1184 endgenerate
philpem@0 1185
philpem@0 1186 endmodule // MASTER_CTRL
philpem@0 1187
philpem@0 1188 `endif // MASTER_CTRL_FILE