OpenCores
URL https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [lib/] [wb_interface.v] - Blame information for rev 37

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OMS 8051 cores common library Module                        ////
4
////                                                              ////
5
////  This file is part of the OMS 8051 cores project             ////
6
////  http://www.opencores.org/cores/oms8051mini/                 ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  OMS 8051 definitions.                                       ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17
////  Revision : Nov 26, 2016                                     //// 
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE.  See the GNU Lesser General Public License for more ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
 
46
module wb_interface (
47
          rst          ,
48
          clk          ,
49
 
50
          dma_req_i    ,
51
          dma_write_i  ,
52
          dma_addr_i   ,
53
          dma_length_i ,
54
          dma_ack_o    ,
55
          dma_done_o   ,
56
 
57
          dma_start_o  ,
58
          dma_wr_o     ,
59
          dma_rd_o     ,
60
          dma_last_o   ,
61
          dma_wdata_i  ,
62
          dma_rdata_o  ,
63
 
64
    // external memory
65
          wbd_dat_i    ,
66
          wbd_dat_o    ,
67
          wbd_adr_o    ,
68
          wbd_be_o     ,
69
          wbd_we_o     ,
70
          wbd_ack_i    ,
71
          wbd_stb_o    ,
72
          wbd_cyc_o    ,
73
          wbd_err_i
74
 
75
 
76
     );
77
 
78
 
79
 
80
input            rst             ;
81
input            clk             ;
82
 
83
input            dma_req_i       ;
84
input            dma_write_i     ;
85
input [25:0]     dma_addr_i      ;
86
input [7:0]      dma_length_i    ;
87
output           dma_ack_o       ;
88
output           dma_done_o      ; // indicates end of DMA transaction
89
 
90
output           dma_start_o     ;
91
output           dma_wr_o        ;
92
output           dma_rd_o        ;
93
output           dma_last_o      ;
94
input  [31:0]    dma_wdata_i     ;
95
output [31:0]    dma_rdata_o     ;
96
 
97
//--------------------------------
98
// WB interface
99
//--------------------------------
100
input  [31:0]    wbd_dat_i       ; // data input
101
output [31:0]    wbd_dat_o       ; // data output
102
output [23:0]    wbd_adr_o       ; // address
103
output  [3:0]    wbd_be_o        ; // byte enable
104
output           wbd_we_o        ; // write 
105
input            wbd_ack_i       ; // acknowlegement
106
output           wbd_stb_o       ; // strobe/request
107
output           wbd_cyc_o       ; // wb cycle
108
input            wbd_err_i       ; // we error
109
 
110
//------------------------------------
111
// Reg Declaration
112
//--------------------------------
113
reg [2:0]        state           ;
114
reg [2:0]        state_d         ;
115
reg [7:0]        preq_len        ; // pending request length in bytes
116
reg              wbd_we_o        ; // westbone write req
117
reg [23:0]       wbd_adr_o       ; // westnone address
118
reg              dma_ack_o       ; // dma ack
119
reg [7:0]        twbtrans        ; // total westbone transaction
120
reg              dma_wr_o        ; // dma write request
121
reg              dma_rd_o        ; // dma read request
122
reg [31:0]       temp_data       ; // temp holding data
123
reg [1:0]        be_sof          ; // Byte enable starting alignment
124
reg [31:0]       wbd_dat_o       ; // westbone data out
125
reg [3:0]        wbd_be_o        ; // west bone byte enable 
126
reg [31:0]       dma_rdata_o     ; // dma read data
127
reg              wbd_stb_o       ;
128
reg              dma_start_o     ; // dma first transfer
129
reg              dma_last_o      ; // dma last transfer
130
 
131
parameter WB_IDLE           = 3'b000;
132
parameter WB_REQ            = 3'b001;
133
parameter WB_WR_PHASE       = 3'b010;
134
parameter WB_RD_PHASE_SOF   = 3'b011;
135
parameter WB_RD_PHASE_CONT  = 3'b100;
136
 
137
assign dma_done_o = (state == WB_IDLE) && (state_d !=  WB_IDLE);
138
 
139
always @(posedge rst or posedge clk)
140
begin
141
   if(rst) begin
142
      state         <= WB_IDLE;
143
      state_d       <= WB_IDLE;
144
      wbd_we_o      <= 0;
145
      wbd_adr_o     <= 0;
146
      preq_len      <= 0;
147
      dma_ack_o     <= 0;
148
      twbtrans      <= 0;
149
      dma_wr_o      <= 0;
150
      dma_rd_o      <= 0;
151
      temp_data     <= 0;
152
      be_sof        <= 0;
153
      wbd_dat_o     <= 0;
154
      wbd_be_o      <= 0;
155
      dma_rdata_o   <= 0;
156
      wbd_stb_o     <= 0;
157
      dma_start_o   <= 0;
158
      dma_last_o    <= 0;
159
   end
160
   else begin
161
      state_d       <= state;
162
      case(state)
163
      WB_IDLE :
164
         begin
165
            if(dma_req_i)
166
            begin
167
               dma_ack_o  <= 1;
168
               wbd_we_o   <= dma_write_i;
169
               wbd_adr_o  <= dma_addr_i[25:2];
170
               be_sof     <= dma_addr_i[1] << 1 + dma_addr_i[0];
171
               preq_len   <= dma_length_i;
172
               // total wb transfer
173
               twbtrans   <= dma_length_i[7:2] +
174
                             |(dma_length_i[1:0]) +
175
                             |(dma_addr_i[1:0]);
176
               state       <= WB_REQ;
177
            end
178
            dma_wr_o   <= 0;
179
            dma_rd_o   <= 0;
180
            wbd_stb_o  <= 0;
181
            dma_start_o  <= 0;
182
         end
183
      WB_REQ :
184
         begin
185
            dma_ack_o      <= 0;
186
            wbd_stb_o      <= 1;
187
            if(wbd_we_o) begin
188
               dma_wr_o    <= 1;
189
               dma_start_o <= 1;
190
               temp_data   <= dma_wdata_i;
191
               if(be_sof == 0) begin
192
                  wbd_dat_o  <= dma_wdata_i;
193
                  wbd_be_o   <= 4'b1111;
194
                  preq_len    <= preq_len - 4;
195
               end
196
               else if(be_sof == 1) begin
197
                  wbd_dat_o  <= {dma_wdata_i[23:0],8'h0};
198
                  wbd_be_o   <= 4'b1110;
199
                  preq_len    <= preq_len - 3;
200
               end
201
               else if(be_sof == 2) begin
202
                  wbd_dat_o  <= {dma_wdata_i[15:0],16'h0};
203
                  wbd_be_o   <= 4'b1100;
204
                  preq_len    <= preq_len - 2;
205
               end
206
               else begin
207
                  wbd_dat_o  <= {dma_wdata_i[7:0],23'h0};
208
                  wbd_be_o   <= 4'b1000;
209
                  preq_len    <= preq_len - 1;
210
               end
211
               twbtrans   <= twbtrans -1;
212
               state      <= WB_WR_PHASE;
213
               if(twbtrans == 1)
214
                   dma_last_o <= 1;
215
            end
216
            else begin
217
               state   <= WB_RD_PHASE_SOF;
218
            end
219
         end
220
      WB_WR_PHASE :
221
         begin
222
            dma_start_o       <= 0;
223
            if(wbd_ack_i) begin
224
               if(twbtrans == 1)
225
                   dma_last_o <= 1;
226
               else
227
                   dma_last_o <= 0;
228
               if(twbtrans > 0) begin
229
                  temp_data   <= dma_wdata_i;
230
                  twbtrans    <= twbtrans -1;
231
                  if(be_sof == 0) begin
232
                     wbd_dat_o  <= dma_wdata_i;
233
                  end
234
                  else if(be_sof == 1) begin
235
                     wbd_dat_o  <= {dma_wdata_i[23:0],temp_data[31:24]};
236
                  end
237
                  else if(be_sof == 2) begin
238
                     wbd_dat_o  <= {dma_wdata_i[15:0],temp_data[31:16]};
239
                  end
240
                  else begin
241
                     wbd_dat_o  <= {dma_wdata_i[7:0],temp_data[31:8]};
242
                  end
243
 
244
                  if(twbtrans > 1) begin // If the Pending Transfer is more than 1
245
                     dma_wr_o   <= 1;
246
                     wbd_be_o   <= 4'b1111;
247
                     preq_len   <= preq_len - 4;
248
                  end
249
                  else begin // for last write access
250
                     wbd_be_o   <= preq_len[1:0] == 2'b00 ? 4'b1111:
251
                                   preq_len[1:0] == 2'b01 ? 4'b0001:
252
                                   preq_len[1:0] == 2'b10 ? 4'b0011: 4'b0111;
253
 
254
                     case({be_sof[1:0],preq_len[1:0]})
255
                        // Start alignment = 0
256
                        4'b0001 : dma_wr_o   <= 1;
257
                        4'b0010 : dma_wr_o   <= 1;
258
                        4'b0011 : dma_wr_o   <= 1;
259
                        4'b0000 : dma_wr_o   <= 1;
260
                        // Start alignment = 1
261
                        4'b0101 : dma_wr_o   <= 0;
262
                        4'b0110 : dma_wr_o   <= 1;
263
                        4'b0111 : dma_wr_o   <= 1;
264
                        4'b0100 : dma_wr_o   <= 1;
265
                        // Start alignment = 2
266
                        4'b1001 : dma_wr_o   <= 0;
267
                        4'b1010 : dma_wr_o   <= 0;
268
                        4'b1011 : dma_wr_o   <= 1;
269
                        4'b1000 : dma_wr_o   <= 1;
270
                        // Start alignment = 3
271
                        4'b1101 : dma_wr_o   <= 0;
272
                        4'b1110 : dma_wr_o   <= 0;
273
                        4'b1111 : dma_wr_o   <= 0;
274
                        4'b1100 : dma_wr_o   <= 1;
275
                     endcase
276
                  end
277
               end
278
               else begin
279
                  dma_wr_o  <= 0;
280
                  wbd_stb_o <= 0;
281
                  state     <= WB_IDLE;
282
               end
283
            end
284
            else begin
285
               dma_last_o <= 0;
286
               dma_wr_o   <= 0;
287
            end
288
         end
289
      WB_RD_PHASE_SOF :
290
         begin
291
            if(wbd_ack_i) begin
292
               twbtrans    <= twbtrans -1;
293
               if(twbtrans == 1) begin // If the Pending Transfer is 1
294
                   dma_rd_o   <= 1;
295
                   dma_start_o<= 1;
296
                   if(be_sof == 0) begin
297
                       dma_rdata_o  <= wbd_dat_i;
298
                       preq_len     <= preq_len - 4;
299
                   end
300
                   else if(be_sof == 1) begin
301
                       dma_rdata_o  <= {8'h0,wbd_dat_i[31:24]};
302
                       preq_len     <= preq_len - 3;
303
                   end
304
                   else if(be_sof == 2) begin
305
                       dma_rdata_o  <= {16'h0,wbd_dat_i[31:16]};
306
                       preq_len     <= preq_len - 2;
307
                   end
308
                   else begin
309
                       dma_rdata_o  <= {23'h0,wbd_dat_i[31:8]};
310
                       preq_len     <= preq_len - 0;
311
                   end
312
                   dma_last_o <= 1;
313
                   state      <= WB_IDLE;
314
               end
315
               else begin // pending transction is more than 1
316
                  if(be_sof == 0) begin
317
                      dma_rdata_o  <= wbd_dat_i;
318
                      dma_rd_o     <= 1;
319
                      dma_start_o  <= 1;
320
                      preq_len     <= preq_len - 4;
321
                  end
322
                  else if(be_sof == 1) begin
323
                      temp_data    <= {8'h0,wbd_dat_i[31:24]};
324
                      dma_rd_o     <= 0;
325
                      preq_len     <= preq_len - 3;
326
                  end
327
                  else if(be_sof == 2) begin
328
                      temp_data   <= {16'h0,wbd_dat_i[31:16]};
329
                      preq_len    <= preq_len - 2;
330
                  end
331
                  else begin
332
                      temp_data   <= {23'h0,wbd_dat_i[31:8]};
333
                      preq_len    <= preq_len - 0;
334
                  end
335
                  state     <= WB_RD_PHASE_CONT;
336
               end
337
            end
338
            else begin
339
               dma_rd_o  <= 0;
340
            end
341
         end
342
      WB_RD_PHASE_CONT:
343
         begin
344
            dma_start_o  <= 0;
345
            if(wbd_ack_i) begin
346
               dma_rd_o         <= 1;
347
               twbtrans         <= twbtrans -1;
348
               if(be_sof == 0) begin
349
                  dma_rdata_o   <= wbd_dat_i;
350
                  preq_len      <= preq_len - 4;
351
               end
352
               else if(be_sof == 1) begin
353
                  dma_rdata_o   <= {wbd_dat_i[7:0],temp_data[23:0]};
354
                  temp_data     <= {8'h0,wbd_dat_i[31:8]};
355
                  preq_len      <= preq_len - 3;
356
               end
357
               else if(be_sof == 2) begin
358
                  dma_rdata_o   <= {wbd_dat_i[15:0],temp_data[15:0]};
359
                  temp_data     <= {16'h0,wbd_dat_i[31:16]};
360
                  preq_len      <= preq_len - 2;
361
               end
362
               else begin
363
                  dma_rdata_o   <= {wbd_dat_i[23:0],temp_data[7:0]};
364
                  temp_data     <= {24'h0,wbd_dat_i[31:23]};
365
                  preq_len      <= preq_len - 1;
366
               end
367
               if(twbtrans == 1) begin  // If the it's last transfer
368
                  dma_last_o <= 1;
369
                  state      <= WB_IDLE;
370
               end
371
            end
372
            else begin
373
               dma_last_o <= 0;
374
               dma_rd_o   <= 0;
375
            end
376
         end
377
      endcase
378
   end
379
end
380
 
381
 
382
 
383
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.