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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [lib/] [wb_interface.v] - Blame information for rev 13

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

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

powered by: WebSVN 2.1.0

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