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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_wb_biu.v] - Blame information for rev 294

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

Line No. Rev Author Line
1 10 unneback
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OR1200's WISHBONE BIU                                       ////
4
////                                                              ////
5
////  This file is part of the OpenRISC 1200 project              ////
6 258 julius
////  http://opencores.org/project,or1k                           ////
7 10 unneback
////                                                              ////
8
////  Description                                                 ////
9
////  Implements WISHBONE interface                               ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   - if biu_cyc/stb are deasserted and wb_ack_i is asserted   ////
13
////   and this happens even before aborted_r is asssrted,        ////
14
////   wb_ack_i will be delivered even though transfer is         ////
15
////   internally considered already aborted. However most        ////
16
////   wb_ack_i are externally registered and delayed. Normally   ////
17
////   this shouldn't cause any problems.                         ////
18
////                                                              ////
19
////  Author(s):                                                  ////
20
////      - Damjan Lampret, lampret@opencores.org                 ////
21
////                                                              ////
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
//
50 142 marcus.erl
// $Log: or1200_wb_biu.v,v $
51
// Revision 2.0  2010/06/30 11:00:00  ORSoC
52
// Major update: 
53
// Structure reordered and bugs fixed. 
54
//
55 10 unneback
 
56
// synopsys translate_off
57
`include "timescale.v"
58
// synopsys translate_on
59
`include "or1200_defines.v"
60
 
61
module or1200_wb_biu(
62 258 julius
                     // RISC clock, reset and clock control
63
                     clk, rst, clmode,
64 10 unneback
 
65 258 julius
                     // WISHBONE interface
66
                     wb_clk_i, wb_rst_i, wb_ack_i, wb_err_i, wb_rty_i, wb_dat_i,
67
                     wb_cyc_o, wb_adr_o, wb_stb_o, wb_we_o, wb_sel_o, wb_dat_o,
68 10 unneback
`ifdef OR1200_WB_CAB
69 258 julius
                     wb_cab_o,
70 10 unneback
`endif
71
`ifdef OR1200_WB_B3
72 258 julius
                     wb_cti_o, wb_bte_o,
73 10 unneback
`endif
74
 
75 258 julius
                     // Internal RISC bus
76
                     biu_dat_i, biu_adr_i, biu_cyc_i, biu_stb_i, biu_we_i, biu_sel_i, biu_cab_i,
77
                     biu_dat_o, biu_ack_o, biu_err_o
78
                     );
79 10 unneback
 
80 258 julius
   parameter dw = `OR1200_OPERAND_WIDTH;
81
   parameter aw = `OR1200_OPERAND_WIDTH;
82 10 unneback
 
83 258 julius
   //
84
   // RISC clock, reset and clock control
85
   //
86
   input                                clk;            // RISC clock
87
   input                                rst;            // RISC reset
88
   input [1:0]                           clmode;         // 00 WB=RISC, 01 WB=RISC/2, 10 N/A, 11 WB=RISC/4
89 10 unneback
 
90 258 julius
   //
91
   // WISHBONE interface
92
   //
93
   input                                wb_clk_i;       // clock input
94
   input                                wb_rst_i;       // reset input
95
   input                                wb_ack_i;       // normal termination
96
   input                                wb_err_i;       // termination w/ error
97
   input                                wb_rty_i;       // termination w/ retry
98
   input [dw-1:0]                        wb_dat_i;       // input data bus
99
   output                               wb_cyc_o;       // cycle valid output
100
   output [aw-1:0]                       wb_adr_o;       // address bus outputs
101
   output                               wb_stb_o;       // strobe output
102
   output                               wb_we_o;        // indicates write transfer
103
   output [3:0]                  wb_sel_o;       // byte select outputs
104
   output [dw-1:0]                       wb_dat_o;       // output data bus
105 10 unneback
`ifdef OR1200_WB_CAB
106 258 julius
   output                               wb_cab_o;       // consecutive address burst
107 10 unneback
`endif
108
`ifdef OR1200_WB_B3
109 258 julius
   output [2:0]                  wb_cti_o;       // cycle type identifier
110
   output [1:0]                  wb_bte_o;       // burst type extension
111 10 unneback
`endif
112
 
113 258 julius
   //
114
   // Internal RISC interface
115
   //
116
   input [dw-1:0]                        biu_dat_i;      // input data bus
117
   input [aw-1:0]                        biu_adr_i;      // address bus
118
   input                                biu_cyc_i;      // WB cycle
119
   input                                biu_stb_i;      // WB strobe
120
   input                                biu_we_i;       // WB write enable
121
   input                                biu_cab_i;      // CAB input
122
   input [3:0]                           biu_sel_i;      // byte selects
123
   output [31:0]                         biu_dat_o;      // output data bus
124
   output                               biu_ack_o;      // ack output
125
   output                               biu_err_o;      // err output
126 10 unneback
 
127 258 julius
   //
128
   // Registers
129
   //
130
   wire                                 wb_ack;         // normal termination
131
   reg [aw-1:0]                  wb_adr_o;       // address bus outputs
132
   reg                                  wb_cyc_o;       // cycle output
133
   reg                                  wb_stb_o;       // strobe output
134
   reg                                  wb_we_o;        // indicates write transfer
135
   reg [3:0]                             wb_sel_o;       // byte select outputs
136 10 unneback
`ifdef OR1200_WB_CAB
137 258 julius
   reg                                  wb_cab_o;       // CAB output
138 10 unneback
`endif
139
`ifdef OR1200_WB_B3
140 258 julius
   reg [2:0]                             wb_cti_o;       // cycle type identifier
141
   reg [1:0]                             wb_bte_o;       // burst type extension
142 10 unneback
`endif
143 258 julius
`ifdef OR1200_NO_DC
144
   reg [dw-1:0]                  wb_dat_o;       // output data bus
145
`else
146
   assign wb_dat_o = biu_dat_i;    // No register on this - straight from DCRAM
147
`endif
148
 
149 10 unneback
`ifdef OR1200_WB_RETRY
150 258 julius
   reg [`OR1200_WB_RETRY-1:0]            retry_cnt;      // Retry counter
151 10 unneback
`else
152 258 julius
   wire                                 retry_cnt;
153
   assign retry_cnt = 1'b0;
154 10 unneback
`endif
155 142 marcus.erl
`ifdef OR1200_WB_B3
156 258 julius
   reg [1:0]                             burst_len;      // burst counter
157 10 unneback
`endif
158
 
159 258 julius
   reg                                  biu_stb_reg;    // WB strobe
160
   wire                                 biu_stb;        // WB strobe
161
   reg                                  wb_cyc_nxt;     // next WB cycle value
162
   reg                                  wb_stb_nxt;     // next WB strobe value
163
   reg [2:0]                             wb_cti_nxt;     // next cycle type identifier value
164 10 unneback
 
165 258 julius
   reg                                  wb_ack_cnt;     // WB ack toggle counter
166
   reg                                  wb_err_cnt;     // WB err toggle counter
167
   reg                                  wb_rty_cnt;     // WB rty toggle counter
168
   reg                                  biu_ack_cnt;    // BIU ack toggle counter
169
   reg                                  biu_err_cnt;    // BIU err toggle counter
170
   reg                                  biu_rty_cnt;    // BIU rty toggle counter
171
   wire                                 biu_rty;        // BIU rty indicator
172 10 unneback
 
173 258 julius
   reg [1:0]                             wb_fsm_state_cur;       // WB FSM - surrent state
174
   reg [1:0]                             wb_fsm_state_nxt;       // WB FSM - next state
175
   wire [1:0]                            wb_fsm_idle     = 2'h0; // WB FSM state - IDLE
176
   wire [1:0]                            wb_fsm_trans    = 2'h1; // WB FSM state - normal TRANSFER
177
   wire [1:0]                            wb_fsm_last     = 2'h2; // EB FSM state - LAST transfer
178 10 unneback
 
179 258 julius
   //
180
   // WISHBONE I/F <-> Internal RISC I/F conversion
181
   //
182
   //assign wb_ack = wb_ack_i;
183
   assign wb_ack = wb_ack_i & !wb_err_i & !wb_rty_i;
184 10 unneback
 
185 258 julius
   //
186
   // WB FSM - register part
187
   // 
188
   always @(posedge wb_clk_i or posedge wb_rst_i) begin
189
      if (wb_rst_i)
190
        wb_fsm_state_cur <=  wb_fsm_idle;
191
      else
192
        wb_fsm_state_cur <=  wb_fsm_state_nxt;
193
   end
194 10 unneback
 
195 258 julius
   //
196
   // WB burst tength counter
197
   // 
198
   always @(posedge wb_clk_i or posedge wb_rst_i) begin
199
      if (wb_rst_i) begin
200
         burst_len <=  2'h0;
201
      end
202
      else begin
203
         // burst counter
204
         if (wb_fsm_state_cur == wb_fsm_idle)
205
           burst_len <=  2'h2;
206
         else if (wb_stb_o & wb_ack)
207
           burst_len <=  burst_len - 1'b1;
208
      end
209
   end
210 10 unneback
 
211 258 julius
   // 
212
   // WB FSM - combinatorial part
213
   // 
214
   always @(wb_fsm_state_cur or burst_len or wb_err_i or wb_rty_i or wb_ack or
215
            wb_cti_o or wb_sel_o or wb_stb_o or wb_we_o or biu_cyc_i or
216
            biu_stb or biu_cab_i or biu_sel_i or biu_we_i) begin
217
      // States of WISHBONE Finite State Machine
218
      case(wb_fsm_state_cur)
219 142 marcus.erl
        // IDLE 
220
        wb_fsm_idle : begin
221 258 julius
           wb_cyc_nxt = biu_cyc_i & biu_stb;
222
           wb_stb_nxt = biu_cyc_i & biu_stb;
223
           wb_cti_nxt = {!biu_cab_i, 1'b1, !biu_cab_i};
224
           if (biu_cyc_i & biu_stb)
225
             wb_fsm_state_nxt = wb_fsm_trans;
226
           else
227
             wb_fsm_state_nxt = wb_fsm_idle;
228 142 marcus.erl
        end
229
        // normal TRANSFER
230
        wb_fsm_trans : begin
231 258 julius
           wb_cyc_nxt = !wb_stb_o | !wb_err_i & !wb_rty_i &
232
                        !(wb_ack & wb_cti_o == 3'b111);
233
 
234
           wb_stb_nxt = !wb_stb_o | !wb_err_i & !wb_rty_i & !wb_ack |
235
                        !wb_err_i & !wb_rty_i & wb_cti_o == 3'b010 /*& !wb_we_o -- Removed to add burst write, JPB*/;
236
 
237
           wb_cti_nxt[2] = wb_stb_o & wb_ack & burst_len == 'h0 | wb_cti_o[2];
238
           wb_cti_nxt[1] = 1'b1  ;
239
           wb_cti_nxt[0] = wb_stb_o & wb_ack & burst_len == 'h0 | wb_cti_o[0];
240
 
241
           //if ((!biu_cyc_i | !biu_stb | !biu_cab_i) & wb_cti_o == 3'b010  | 
242
           //     biu_sel_i != wb_sel_o | biu_we_i != wb_we_o)
243
 
244
           if ((!biu_cyc_i | !biu_stb | !biu_cab_i | biu_sel_i != wb_sel_o |
245
                biu_we_i != wb_we_o) & wb_cti_o == 3'b010)
246
             wb_fsm_state_nxt = wb_fsm_last;
247
           else if ((wb_err_i | wb_rty_i | wb_ack & wb_cti_o==3'b111) &
248
                    wb_stb_o)
249
             wb_fsm_state_nxt = wb_fsm_idle;
250
           else
251
             wb_fsm_state_nxt = wb_fsm_trans;
252 142 marcus.erl
        end
253
        // LAST transfer
254
        wb_fsm_last : begin
255 258 julius
           wb_cyc_nxt = !wb_stb_o | !wb_err_i & !wb_rty_i &
256
                        !(wb_ack & wb_cti_o == 3'b111);
257
           wb_stb_nxt = !wb_stb_o | !wb_err_i & !wb_rty_i &
258
                        !(wb_ack & wb_cti_o == 3'b111);
259
           wb_cti_nxt[2] = wb_ack & wb_stb_o | wb_cti_o[2];
260
           wb_cti_nxt[1] = 1'b1                  ;
261
           wb_cti_nxt[0] = wb_ack & wb_stb_o | wb_cti_o[0];
262
           if ((wb_err_i | wb_rty_i | wb_ack & wb_cti_o == 3'b111) & wb_stb_o)
263
             wb_fsm_state_nxt = wb_fsm_idle;
264
           else
265
             wb_fsm_state_nxt = wb_fsm_last;
266 142 marcus.erl
        end
267
        // default state
268
        default:begin
269 258 julius
           wb_cyc_nxt = 1'bx;
270
           wb_stb_nxt = 1'bx;
271
           wb_cti_nxt = 3'bxxx;
272
           wb_fsm_state_nxt = 2'bxx;
273 142 marcus.erl
        end
274 258 julius
      endcase
275
   end
276 10 unneback
 
277 258 julius
   //
278
   // WB FSM - output signals
279
   // 
280
   always @(posedge wb_clk_i or posedge wb_rst_i) begin
281
      if (wb_rst_i) begin
282
         wb_cyc_o       <=  1'b0;
283
         wb_stb_o       <=  1'b0;
284
         wb_cti_o       <=  3'b111;
285
         wb_bte_o       <=  2'b01;      // 4-beat wrap burst = constant
286 142 marcus.erl
`ifdef OR1200_WB_CAB
287 258 julius
         wb_cab_o       <=  1'b0;
288 10 unneback
`endif
289 258 julius
         wb_we_o                <=  1'b0;
290
         wb_sel_o       <=  4'hf;
291
         wb_adr_o       <=  {aw{1'b0}};
292
`ifdef OR1200_NO_DC
293
         wb_dat_o       <=  {dw{1'b0}};
294
`endif
295
      end
296
      else begin
297
         wb_cyc_o       <=  wb_cyc_nxt;
298
         //             wb_stb_o        <=  wb_stb_nxt;
299
         if (wb_ack & wb_cti_o == 3'b111)
300
           wb_stb_o        <=  1'b0;
301
         else
302
           wb_stb_o        <=  wb_stb_nxt;
303
         wb_cti_o       <=  wb_cti_nxt;
304
         wb_bte_o       <=  2'b01;      // 4-beat wrap burst = constant
305 142 marcus.erl
`ifdef OR1200_WB_CAB
306 258 julius
         wb_cab_o       <=  biu_cab_i;
307 10 unneback
`endif
308 258 julius
         // we and sel - set at beginning of access 
309
         if (wb_fsm_state_cur == wb_fsm_idle) begin
310
            wb_we_o             <=  biu_we_i;
311
            wb_sel_o    <=  biu_sel_i;
312
         end
313
         // adr - set at beginning of access and changed at every termination 
314
         if (wb_fsm_state_cur == wb_fsm_idle) begin
315
            wb_adr_o    <=  biu_adr_i;
316
         end
317
         else if (wb_stb_o & wb_ack) begin
318
            wb_adr_o[3:2]       <=  wb_adr_o[3:2] + 1'b1;
319
         end
320
`ifdef OR1200_NO_DC
321
         // dat - write data changed after avery subsequent write access
322
         if (!wb_stb_o) begin
323
            wb_dat_o    <=  biu_dat_i;
324
         end
325
`endif
326
      end
327
   end
328 10 unneback
 
329 258 julius
   //
330
   // WB & BIU termination toggle counters
331
   // 
332
   always @(posedge wb_clk_i or posedge wb_rst_i) begin
333
      if (wb_rst_i) begin
334
         wb_ack_cnt     <=  1'b0;
335
         wb_err_cnt     <=  1'b0;
336
         wb_rty_cnt     <=  1'b0;
337
      end
338
      else begin
339
         // WB ack toggle counter
340
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
341
           wb_ack_cnt   <=  1'b0;
342
         else if (wb_stb_o & wb_ack)
343
           wb_ack_cnt   <=  !wb_ack_cnt;
344
         // WB err toggle counter
345
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
346
           wb_err_cnt   <=  1'b0;
347
         else if (wb_stb_o & wb_err_i)
348
           wb_err_cnt   <=  !wb_err_cnt;
349
         // WB rty toggle counter
350
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
351
           wb_rty_cnt   <=  1'b0;
352
         else if (wb_stb_o & wb_rty_i)
353
           wb_rty_cnt   <=  !wb_rty_cnt;
354
      end
355
   end
356 10 unneback
 
357 258 julius
   always @(posedge clk or posedge rst) begin
358
      if (rst) begin
359
         biu_stb_reg    <=  1'b0;
360
         biu_ack_cnt    <=  1'b0;
361
         biu_err_cnt    <=  1'b0;
362
         biu_rty_cnt    <=  1'b0;
363 142 marcus.erl
`ifdef OR1200_WB_RETRY
364 258 julius
         retry_cnt      <= {`OR1200_WB_RETRY{1'b0}};
365 10 unneback
`endif
366 258 julius
      end
367
      else begin
368
         // BIU strobe
369
         if (biu_stb_i & !biu_cab_i & biu_ack_o)
370
           biu_stb_reg  <=  1'b0;
371
         else
372
           biu_stb_reg  <=  biu_stb_i;
373
         // BIU ack toggle counter
374
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
375
           biu_ack_cnt  <=  1'b0 ;
376
         else if (biu_ack_o)
377
           biu_ack_cnt  <=  !biu_ack_cnt ;
378
         // BIU err toggle counter
379
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
380
           biu_err_cnt  <=  1'b0 ;
381
         else if (wb_err_i & biu_err_o)
382
           biu_err_cnt  <=  !biu_err_cnt ;
383
         // BIU rty toggle counter
384
         if (wb_fsm_state_cur == wb_fsm_idle | !clmode)
385
           biu_rty_cnt  <=  1'b0 ;
386
         else if (biu_rty)
387
           biu_rty_cnt  <=  !biu_rty_cnt ;
388 142 marcus.erl
`ifdef OR1200_WB_RETRY
389 258 julius
         if (biu_ack_o | biu_err_o)
390
           retry_cnt    <=  {`OR1200_WB_RETRY{1'b0}};
391
         else if (biu_rty)
392
           retry_cnt    <=  retry_cnt + 1'b1;
393 10 unneback
`endif
394 258 julius
      end
395
   end
396 10 unneback
 
397 258 julius
   assign biu_stb = biu_stb_i & biu_stb_reg;
398 10 unneback
 
399 258 julius
   //
400
   // Input BIU data bus
401
   //
402
   assign       biu_dat_o       = wb_dat_i;
403 10 unneback
 
404 258 julius
   //
405
   // Input BIU termination signals 
406
   //
407
   assign       biu_rty         = (wb_fsm_state_cur == wb_fsm_trans) & wb_rty_i & wb_stb_o & (wb_rty_cnt ~^ biu_rty_cnt);
408
   assign       biu_ack_o       = (wb_fsm_state_cur == wb_fsm_trans) & wb_ack & wb_stb_o & (wb_ack_cnt ~^ biu_ack_cnt);
409
   assign       biu_err_o       = (wb_fsm_state_cur == wb_fsm_trans) & wb_err_i & wb_stb_o & (wb_err_cnt ~^ biu_err_cnt)
410 142 marcus.erl
`ifdef OR1200_WB_RETRY
411 258 julius
     | biu_rty & retry_cnt[`OR1200_WB_RETRY-1];
412 10 unneback
`else
413 258 julius
   ;
414 10 unneback
`endif
415
 
416
 
417
endmodule

powered by: WebSVN 2.1.0

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