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

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [lib/] [wb_interface.v] - Blame information for rev 5

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

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

powered by: WebSVN 2.1.0

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