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

Subversion Repositories turbo8051

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

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 [7:0]        twbtrans        ; // total westbone transaction
118
reg              dma_wr_o        ; // dma write request
119
reg              dma_rd_o        ; // dma read request
120
reg [31:0]       temp_data       ; // temp holding data
121
reg [1:0]        be_sof          ; // Byte enable starting alignment
122
reg [31:0]       wbd_dat_o       ; // westbone data out
123
reg [3:0]        wbd_be_o        ; // west bone byte enable 
124
reg [31:0]       dma_rdata_o     ; // dma read data
125
reg              wbd_stb_o       ;
126
reg              dma_start_o     ; // dma first transfer
127
reg              dma_last_o      ; // dma last transfer
128
 
129
parameter WB_IDLE           = 3'b000;
130
parameter WB_REQ            = 3'b001;
131
parameter WB_WR_PHASE       = 3'b010;
132
parameter WB_RD_PHASE_SOF   = 3'b011;
133
parameter WB_RD_PHASE_CONT  = 3'b100;
134
 
135
assign dma_done_o = (state == WB_IDLE) && (state_d !=  WB_IDLE);
136
 
137
always @(posedge rst or posedge clk)
138
begin
139
   if(rst) begin
140
      state         <= WB_IDLE;
141
      state_d       <= WB_IDLE;
142
      wbd_we_o      <= 0;
143
      wbd_adr_o     <= 0;
144
      preq_len      <= 0;
145
      dma_ack_o     <= 0;
146
      twbtrans      <= 0;
147
      dma_wr_o      <= 0;
148
      dma_rd_o      <= 0;
149
      temp_data     <= 0;
150
      be_sof        <= 0;
151
      wbd_dat_o     <= 0;
152
      wbd_be_o      <= 0;
153
      dma_rdata_o   <= 0;
154
      wbd_stb_o     <= 0;
155
      dma_start_o   <= 0;
156
      dma_last_o    <= 0;
157
   end
158
   else begin
159
      state_d       <= state;
160
      case(state)
161
      WB_IDLE :
162
         begin
163
            if(dma_req_i)
164
            begin
165
               dma_ack_o  <= 1;
166
               wbd_we_o   <= dma_write_i;
167
               wbd_adr_o  <= dma_addr_i[25:2];
168
               be_sof     <= dma_addr_i[1] << 1 + dma_addr_i[0];
169
               preq_len   <= dma_length_i;
170
               // total wb transfer
171
               twbtrans   <= dma_length_i[7:2] +
172
                             |(dma_length_i[1:0]) +
173
                             |(dma_addr_i[1:0]);
174
               state       <= WB_REQ;
175
            end
176
            dma_wr_o   <= 0;
177
            dma_rd_o   <= 0;
178
            wbd_stb_o  <= 0;
179
            dma_start_o  <= 0;
180
         end
181
      WB_REQ :
182
         begin
183
            dma_ack_o      <= 0;
184
            wbd_stb_o      <= 1;
185
            if(wbd_we_o) begin
186
               dma_wr_o    <= 1;
187
               dma_start_o <= 1;
188
               temp_data   <= dma_wdata_i;
189
               if(be_sof == 0) begin
190
                  wbd_dat_o  <= dma_wdata_i;
191
                  wbd_be_o   <= 4'b1111;
192
                  preq_len    <= preq_len - 4;
193
               end
194
               else if(be_sof == 1) begin
195
                  wbd_dat_o  <= {dma_wdata_i[23:0],8'h0};
196
                  wbd_be_o   <= 4'b1110;
197
                  preq_len    <= preq_len - 3;
198
               end
199
               else if(be_sof == 2) begin
200
                  wbd_dat_o  <= {dma_wdata_i[15:0],16'h0};
201
                  wbd_be_o   <= 4'b1100;
202
                  preq_len    <= preq_len - 2;
203
               end
204
               else begin
205
                  wbd_dat_o  <= {dma_wdata_i[7:0],23'h0};
206
                  wbd_be_o   <= 4'b1000;
207
                  preq_len    <= preq_len - 1;
208
               end
209
               twbtrans   <= twbtrans -1;
210
               state      <= WB_WR_PHASE;
211
               if(twbtrans == 1)
212
                   dma_last_o <= 1;
213
            end
214
            else begin
215
               state   <= WB_RD_PHASE_SOF;
216
            end
217
         end
218
      WB_WR_PHASE :
219
         begin
220
            dma_start_o       <= 0;
221
            if(wbd_ack_i) begin
222
               if(twbtrans == 1)
223
                   dma_last_o <= 1;
224
               else
225
                   dma_last_o <= 0;
226
               if(twbtrans > 0) begin
227
                  temp_data   <= dma_wdata_i;
228
                  twbtrans    <= twbtrans -1;
229
                  if(be_sof == 0) begin
230
                     wbd_dat_o  <= dma_wdata_i;
231
                  end
232
                  else if(be_sof == 1) begin
233
                     wbd_dat_o  <= {dma_wdata_i[23:0],temp_data[31:24]};
234
                  end
235
                  else if(be_sof == 2) begin
236
                     wbd_dat_o  <= {dma_wdata_i[15:0],temp_data[31:16]};
237
                  end
238
                  else begin
239
                     wbd_dat_o  <= {dma_wdata_i[7:0],temp_data[31:8]};
240
                  end
241
 
242
                  if(twbtrans > 1) begin // If the Pending Transfer is more than 1
243
                     dma_wr_o   <= 1;
244
                     wbd_be_o   <= 4'b1111;
245
                     preq_len   <= preq_len - 4;
246
                  end
247
                  else begin // for last write access
248
                     wbd_be_o   <= preq_len[1:0] == 2'b00 ? 4'b1111:
249
                                   preq_len[1:0] == 2'b01 ? 4'b0001:
250
                                   preq_len[1:0] == 2'b10 ? 4'b0011: 4'b0111;
251
 
252
                     case({be_sof[1:0],preq_len[1:0]})
253
                        // Start alignment = 0
254
                        4'b0001 : dma_wr_o   <= 1;
255
                        4'b0010 : dma_wr_o   <= 1;
256
                        4'b0011 : dma_wr_o   <= 1;
257
                        4'b0000 : dma_wr_o   <= 1;
258
                        // Start alignment = 1
259
                        4'b0101 : dma_wr_o   <= 0;
260
                        4'b0110 : dma_wr_o   <= 1;
261
                        4'b0111 : dma_wr_o   <= 1;
262
                        4'b0100 : dma_wr_o   <= 1;
263
                        // Start alignment = 2
264
                        4'b1001 : dma_wr_o   <= 0;
265
                        4'b1010 : dma_wr_o   <= 0;
266
                        4'b1011 : dma_wr_o   <= 1;
267
                        4'b1000 : dma_wr_o   <= 1;
268
                        // Start alignment = 3
269
                        4'b1101 : dma_wr_o   <= 0;
270
                        4'b1110 : dma_wr_o   <= 0;
271
                        4'b1111 : dma_wr_o   <= 0;
272
                        4'b1100 : dma_wr_o   <= 1;
273
                     endcase
274
                  end
275
               end
276
               else begin
277
                  dma_wr_o  <= 0;
278
                  wbd_stb_o <= 0;
279
                  state     <= WB_IDLE;
280
               end
281
            end
282
            else begin
283
               dma_last_o <= 0;
284
               dma_wr_o   <= 0;
285
            end
286
         end
287
      WB_RD_PHASE_SOF :
288
         begin
289
            if(wbd_ack_i) begin
290
               twbtrans    <= twbtrans -1;
291
               if(twbtrans == 1) begin // If the Pending Transfer is 1
292
                   dma_rd_o   <= 1;
293
                   dma_start_o<= 1;
294
                   if(be_sof == 0) begin
295
                       dma_rdata_o  <= wbd_dat_i;
296
                       preq_len     <= preq_len - 4;
297
                   end
298
                   else if(be_sof == 1) begin
299
                       dma_rdata_o  <= {8'h0,wbd_dat_i[31:24]};
300
                       preq_len     <= preq_len - 3;
301
                   end
302
                   else if(be_sof == 2) begin
303
                       dma_rdata_o  <= {16'h0,wbd_dat_i[31:16]};
304
                       preq_len     <= preq_len - 2;
305
                   end
306
                   else begin
307
                       dma_rdata_o  <= {23'h0,wbd_dat_i[31:8]};
308
                       preq_len     <= preq_len - 0;
309
                   end
310
                   dma_last_o <= 1;
311
                   state      <= WB_IDLE;
312
               end
313
               else begin // pending transction is more than 1
314
                  if(be_sof == 0) begin
315
                      dma_rdata_o  <= wbd_dat_i;
316
                      dma_rd_o     <= 1;
317
                      dma_start_o  <= 1;
318
                      preq_len     <= preq_len - 4;
319
                  end
320
                  else if(be_sof == 1) begin
321
                      temp_data    <= {8'h0,wbd_dat_i[31:24]};
322
                      dma_rd_o     <= 0;
323
                      preq_len     <= preq_len - 3;
324
                  end
325
                  else if(be_sof == 2) begin
326
                      temp_data   <= {16'h0,wbd_dat_i[31:16]};
327
                      preq_len    <= preq_len - 2;
328
                  end
329
                  else begin
330
                      temp_data   <= {23'h0,wbd_dat_i[31:8]};
331
                      preq_len    <= preq_len - 0;
332
                  end
333
                  state     <= WB_RD_PHASE_CONT;
334
               end
335
            end
336
            else begin
337
               dma_rd_o  <= 0;
338
            end
339
         end
340
      WB_RD_PHASE_CONT:
341
         begin
342
            dma_start_o  <= 0;
343
            if(wbd_ack_i) begin
344
               dma_rd_o         <= 1;
345
               twbtrans         <= twbtrans -1;
346
               if(be_sof == 0) begin
347
                  dma_rdata_o   <= wbd_dat_i;
348
                  preq_len      <= preq_len - 4;
349
               end
350
               else if(be_sof == 1) begin
351
                  dma_rdata_o   <= {wbd_dat_i[7:0],temp_data[23:0]};
352
                  temp_data     <= {8'h0,wbd_dat_i[31:8]};
353
                  preq_len      <= preq_len - 3;
354
               end
355
               else if(be_sof == 2) begin
356
                  dma_rdata_o   <= {wbd_dat_i[15:0],temp_data[15:0]};
357
                  temp_data     <= {16'h0,wbd_dat_i[31:16]};
358
                  preq_len      <= preq_len - 2;
359
               end
360
               else begin
361
                  dma_rdata_o   <= {wbd_dat_i[23:0],temp_data[7:0]};
362
                  temp_data     <= {24'h0,wbd_dat_i[31:23]};
363
                  preq_len      <= preq_len - 1;
364
               end
365
               if(twbtrans == 1) begin  // If the it's last transfer
366
                  dma_last_o <= 1;
367
                  state      <= WB_IDLE;
368
               end
369
            end
370
            else begin
371
               dma_last_o <= 0;
372
               dma_rd_o   <= 0;
373
            end
374
         end
375
      endcase
376
   end
377
end
378
 
379
 
380
 
381
endmodule

powered by: WebSVN 2.1.0

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