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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [adv_debug_sys/] [Hardware/] [adv_dbg_if/] [rtl/] [verilog/] [adbg_wb_biu.v] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 xianfeng
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  adbg_wb_biu.v                                               ////
4
////                                                              ////
5
////                                                              ////
6
////  This file is part of the SoC Debug Interface.               ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////       Nathan Yawn (nathan.yawn@opencores.org)                ////
10
////                                                              ////
11
////                                                              ////
12
////                                                              ////
13
//////////////////////////////////////////////////////////////////////
14
////                                                              ////
15
//// Copyright (C) 2008-2010        Authors                       ////
16
////                                                              ////
17
//// This source file may be used and distributed without         ////
18
//// restriction provided that this copyright statement is not    ////
19
//// removed from the file and that any derivative work contains  ////
20
//// the original copyright notice and the associated disclaimer. ////
21
////                                                              ////
22
//// This source file is free software; you can redistribute it   ////
23
//// and/or modify it under the terms of the GNU Lesser General   ////
24
//// Public License as published by the Free Software Foundation; ////
25
//// either version 2.1 of the License, or (at your option) any   ////
26
//// later version.                                               ////
27
////                                                              ////
28
//// This source is distributed in the hope that it will be       ////
29
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
30
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
31
//// PURPOSE.  See the GNU Lesser General Public License for more ////
32
//// details.                                                     ////
33
////                                                              ////
34
//// You should have received a copy of the GNU Lesser General    ////
35
//// Public License along with this source; if not, download it   ////
36
//// from http://www.opencores.org/lgpl.shtml                     ////
37
////                                                              ////
38
//////////////////////////////////////////////////////////////////////
39
//
40
// CVS Revision History
41
//
42
// $Log: adbg_wb_biu.v,v $
43
// Revision 1.4  2010-01-10 22:54:11  Nathan
44
// Update copyright dates
45
//
46
// Revision 1.3  2009/05/17 20:54:57  Nathan
47
// Changed email address to opencores.org
48
//
49
// Revision 1.2  2009/05/04 00:50:10  Nathan
50
// Changed the WB BIU to use big-endian byte ordering, to match the OR1000.  Kept little-endian ordering as a compile-time option in case this is ever used with a little-endian CPU.
51
//
52
// Revision 1.1  2008/07/22 20:28:32  Nathan
53
// Changed names of all files and modules (prefixed an a, for advanced).  Cleanup, indenting.  No functional changes.
54
//
55
// Revision 1.4  2008/07/08 19:04:04  Nathan
56
// Many small changes to eliminate compiler warnings, no functional changes.  
57
// System will now pass SRAM and CPU self-tests on Altera FPGA using 
58
// altera_virtual_jtag TAP.
59
//
60
 
61
`include "adbg_wb_defines.v"
62
 
63
// Top module
64
module adbg_wb_biu
65
  (
66
   // Debug interface signals
67
   tck_i,
68
   rst_i,
69
   data_i,
70
   data_o,
71
   addr_i,
72
   strobe_i,
73
   rd_wrn_i,           // If 0, then write op
74
   rdy_o,
75
   err_o,
76
   word_size_i,  // 1,2, or 4
77
 
78
   // Wishbone signals
79
   wb_clk_i,
80
   wb_adr_o,
81
   wb_dat_o,
82
   wb_dat_i,
83
   wb_cyc_o,
84
   wb_stb_o,
85
   wb_sel_o,
86
   wb_we_o,
87
   wb_ack_i,
88
   wb_cab_o,
89
   wb_err_i,
90
   wb_cti_o,
91
   wb_bte_o
92
   );
93
 
94
   // Debug interface signals
95
   input tck_i;
96
   input rst_i;
97
   input [31:0] data_i;  // Assume short words are in UPPER order bits!
98
   output [31:0] data_o;
99
   input [31:0]  addr_i;
100
   input         strobe_i;
101
   input         rd_wrn_i;
102
   output        rdy_o;
103
   output        err_o;
104
   input [2:0]    word_size_i;
105
 
106
   // Wishbone signals
107
   input         wb_clk_i;
108
   output [31:0] wb_adr_o;
109
   output [31:0] wb_dat_o;
110
   input [31:0]  wb_dat_i;
111
   output        wb_cyc_o;
112
   output        wb_stb_o;
113
   output [3:0]  wb_sel_o;
114
   output        wb_we_o;
115
   input         wb_ack_i;
116
   output        wb_cab_o;
117
   input         wb_err_i;
118
   output [2:0]  wb_cti_o;
119
   output [1:0]  wb_bte_o;
120
 
121
   wire [31:0]    data_o;
122
   reg           rdy_o;
123
   wire          err_o;
124
 
125
   wire [31:0]    wb_adr_o;
126
   reg           wb_cyc_o;
127
   reg           wb_stb_o;
128
   wire [31:0]    wb_dat_o;
129
   wire [3:0]     wb_sel_o;
130
   wire          wb_we_o;
131
   wire          wb_cab_o;
132
   wire [2:0]     wb_cti_o;
133
   wire [1:0]     wb_bte_o;
134
 
135
 
136
   // Registers
137
   reg [3:0]      sel_reg;
138
   reg [29:0]     addr_reg;  // Don't need the two LSB, this info is in the SEL bits
139
   reg [31:0]     data_in_reg;  // dbg->WB
140
   reg [31:0]     data_out_reg;  // WB->dbg
141
   reg           wr_reg;
142
   reg           str_sync;  // This is 'active-toggle' rather than -high or -low.
143
   reg           rdy_sync;  // ditto, active-toggle
144
   reg           err_reg;
145
 
146
   // Sync registers.  TFF indicates TCK domain, WBFF indicates wb_clk domain
147
   reg           rdy_sync_tff1;
148
   reg           rdy_sync_tff2;
149
   reg           rdy_sync_tff2q;  // used to detect toggles
150
   reg           str_sync_wbff1;
151
   reg           str_sync_wbff2;
152
   reg           str_sync_wbff2q;  // used to detect toggles
153
 
154
 
155
   // Control Signals
156
   reg           data_o_en;    // latch wb_data_i
157
   reg           rdy_sync_en;  // toggle the rdy_sync signal, indicate ready to TCK domain
158
   reg           err_en;       // latch the wb_err_i signal
159
 
160
   // Internal signals
161
   reg [3:0]      be_dec;  // word_size and low-order address bits decoded to SEL bits
162
   wire          start_toggle;  // WB domain, indicates a toggle on the start strobe
163
   reg [31:0]     swapped_data_i;
164
   reg [31:0]     swapped_data_out;
165
 
166
   //////////////////////////////////////////////////////
167
   // TCK clock domain
168
   // There is no FSM here, just signal latching and clock
169
   // domain synchronization
170
 
171
   // Create byte enable signals from word_size and address (combinatorial)
172
 `ifdef DBG_WB_LITTLE_ENDIAN
173
   // This uses LITTLE ENDIAN byte ordering...lowest-addressed bytes is the
174
   // least-significant byte of the 32-bit WB bus.
175
   always @ (word_size_i or addr_i)
176
     begin
177
        case (word_size_i)
178
          3'h1:
179
            begin
180
               if(addr_i[1:0] == 2'b00) be_dec <= 4'b0001;
181
               else if(addr_i[1:0] == 2'b01) be_dec <= 4'b0010;
182
               else if(addr_i[1:0] == 2'b10) be_dec <= 4'b0100;
183
               else be_dec <= 4'b1000;
184
            end
185
          3'h2:
186
            begin
187
               if(addr_i[1]) be_dec <= 4'b1100;
188
               else          be_dec <= 4'b0011;
189
            end
190
          3'h4: be_dec <= 4'b1111;
191
          default: be_dec <= 4'b1111;  // default to 32-bit access
192
        endcase
193
     end
194
 `else
195
   // This is for a BIG ENDIAN CPU...lowest-addressed byte is 
196
   // the 8 most significant bits of the 32-bit WB bus.
197
   always @ (word_size_i or addr_i)
198
     begin
199
        case (word_size_i)
200
          3'h1:
201
            begin
202
               if(addr_i[1:0] == 2'b00) be_dec <= 4'b1000;
203
               else if(addr_i[1:0] == 2'b01) be_dec <= 4'b0100;
204
               else if(addr_i[1:0] == 2'b10) be_dec <= 4'b0010;
205
               else be_dec <= 4'b0001;
206
            end
207
          3'h2:
208
            begin
209
               if(addr_i[1] == 1'b1) be_dec <= 4'b0011;
210
               else                  be_dec <= 4'b1100;
211
            end
212
          3'h4: be_dec <= 4'b1111;
213
          default: be_dec <= 4'b1111;  // default to 32-bit access
214
        endcase
215
     end
216
 `endif
217
 
218
 
219
   // Byte- or word-swap data as necessary.  Use the non-latched be_dec signal,
220
   // since it and the swapped data will be latched at the same time.
221
   // Remember that since the data is shifted in LSB-first, shorter words
222
   // will be in the high-order bits. (combinatorial)
223
   always @ (be_dec or data_i)
224
     begin
225
        case (be_dec)
226
          4'b1111: swapped_data_i <= data_i;
227
          4'b0011: swapped_data_i <= {16'h0,data_i[31:16]};
228
          4'b1100: swapped_data_i <= data_i;
229
          4'b0001: swapped_data_i <= {24'h0, data_i[31:24]};
230
          4'b0010: swapped_data_i <= {16'h0, data_i[31:24], 8'h0};
231
          4'b0100: swapped_data_i <= {8'h0, data_i[31:24], 16'h0};
232
          4'b1000: swapped_data_i <= {data_i[31:24], 24'h0};
233
          default: swapped_data_i <= data_i;  // Shouldn't be possible
234
        endcase
235
     end
236
 
237
   // Latch input data on 'start' strobe, if ready.
238
   always @ (posedge tck_i or posedge rst_i)
239
     begin
240
        if(rst_i) begin
241
           sel_reg <= 4'h0;
242
           addr_reg <= 30'h0;
243
           data_in_reg <= 32'h0;
244
           wr_reg <= 1'b0;
245
        end
246
        else
247
          if(strobe_i && rdy_o) begin
248
             sel_reg <= be_dec;
249
             addr_reg <= addr_i[31:2];
250
             if(!rd_wrn_i) data_in_reg <= swapped_data_i;
251
             wr_reg <= ~rd_wrn_i;
252
          end
253
     end
254
 
255
   // Create toggle-active strobe signal for clock sync.  This will start a transaction
256
   // on the WB once the toggle propagates to the FSM in the WB domain.
257
   always @ (posedge tck_i or posedge rst_i)
258
     begin
259
        if(rst_i) str_sync <= 1'b0;
260
        else if(strobe_i && rdy_o) str_sync <= ~str_sync;
261
     end
262
 
263
   // Create rdy_o output.  Set on reset, clear on strobe (if set), set on input toggle
264
   always @ (posedge tck_i or posedge rst_i)
265
     begin
266
        if(rst_i) begin
267
           rdy_sync_tff1 <= 1'b0;
268
           rdy_sync_tff2 <= 1'b0;
269
           rdy_sync_tff2q <= 1'b0;
270
           rdy_o <= 1'b1;
271
        end
272
        else begin
273
           rdy_sync_tff1 <= rdy_sync;       // Synchronize the ready signal across clock domains
274
           rdy_sync_tff2 <= rdy_sync_tff1;
275
           rdy_sync_tff2q <= rdy_sync_tff2;  // used to detect toggles
276
 
277
           if(strobe_i && rdy_o) rdy_o <= 1'b0;
278
           else if(rdy_sync_tff2 != rdy_sync_tff2q) rdy_o <= 1'b1;
279
        end
280
 
281
     end
282
 
283
   //////////////////////////////////////////////////////////
284
   // Direct assignments, unsynchronized
285
 
286
   assign wb_dat_o = data_in_reg;
287
   assign wb_we_o = wr_reg;
288
   assign wb_adr_o = {addr_reg, 2'h0};
289
   assign wb_sel_o = sel_reg;
290
 
291
   assign data_o = data_out_reg;
292
   assign err_o = err_reg;
293
 
294
   assign wb_cti_o = 3'h0;
295
   assign wb_bte_o = 2'h0;
296
   assign wb_cab_o = 1'b0;
297
 
298
   ///////////////////////////////////////////////////////
299
   // Wishbone clock domain
300
 
301
    // synchronize the start strobe
302
    always @ (posedge wb_clk_i or posedge rst_i)
303
          begin
304
             if(rst_i) begin
305
                str_sync_wbff1 <= 1'b0;
306
                str_sync_wbff2 <= 1'b0;
307
                str_sync_wbff2q <= 1'b0;
308
             end
309
             else begin
310
                str_sync_wbff1 <= str_sync;
311
                str_sync_wbff2 <= str_sync_wbff1;
312
                str_sync_wbff2q <= str_sync_wbff2;  // used to detect toggles
313
             end
314
          end
315
 
316
   assign start_toggle = (str_sync_wbff2 != str_sync_wbff2q);
317
 
318
   // Error indicator register
319
   always @ (posedge wb_clk_i or posedge rst_i)
320
     begin
321
        if(rst_i) err_reg <= 1'b0;
322
        else if(err_en) err_reg <= wb_err_i;
323
     end
324
 
325
   // Byte- or word-swap the WB->dbg data, as necessary (combinatorial)
326
   // We assume bits not required by SEL are don't care.  We reuse assignments
327
   // where possible to keep the MUX smaller.  (combinatorial)
328
   always @ (sel_reg or wb_dat_i)
329
     begin
330
        case (sel_reg)
331
          4'b1111: swapped_data_out <= wb_dat_i;
332
          4'b0011: swapped_data_out <= wb_dat_i;
333
          4'b1100: swapped_data_out <= {16'h0, wb_dat_i[31:16]};
334
          4'b0001: swapped_data_out <= wb_dat_i;
335
          4'b0010: swapped_data_out <= {24'h0, wb_dat_i[15:8]};
336
          4'b0100: swapped_data_out <= {16'h0, wb_dat_i[31:16]};
337
          4'b1000: swapped_data_out <= {24'h0, wb_dat_i[31:24]};
338
          default: swapped_data_out <= wb_dat_i;  // Shouldn't be possible
339
        endcase
340
     end
341
 
342
   // WB->dbg data register
343
   always @ (posedge wb_clk_i or posedge rst_i)
344
     begin
345
        if(rst_i) data_out_reg <= 32'h0;
346
        else if(data_o_en) data_out_reg <= swapped_data_out;
347
     end
348
 
349
   // Create a toggle-active ready signal to send to the TCK domain
350
   always @ (posedge wb_clk_i or posedge rst_i)
351
     begin
352
        if(rst_i) rdy_sync <= 1'b0;
353
        else if(rdy_sync_en) rdy_sync <= ~rdy_sync;
354
     end
355
 
356
   /////////////////////////////////////////////////////
357
   // Small state machine to create WB accesses
358
   // Not much more that an 'in_progress' bit, but easier
359
   // to read.  Deals with single-cycle and multi-cycle
360
   // accesses.
361
 
362
   reg wb_fsm_state;
363
   reg next_fsm_state;
364
 
365
`define STATE_IDLE     1'h0
366
`define STATE_TRANSFER 1'h1
367
 
368
   // Sequential bit
369
   always @ (posedge wb_clk_i or posedge rst_i)
370
     begin
371
        if(rst_i) wb_fsm_state <= `STATE_IDLE;
372
        else wb_fsm_state <= next_fsm_state;
373
     end
374
 
375
   // Determination of next state (combinatorial)
376
   always @ (wb_fsm_state or start_toggle or wb_ack_i or wb_err_i)
377
     begin
378
        case (wb_fsm_state)
379
          `STATE_IDLE:
380
            begin
381
               if(start_toggle && !(wb_ack_i || wb_err_i)) next_fsm_state <= `STATE_TRANSFER;  // Don't go to next state for 1-cycle transfer
382
               else next_fsm_state <= `STATE_IDLE;
383
            end
384
          `STATE_TRANSFER:
385
            begin
386
               if(wb_ack_i || wb_err_i) next_fsm_state <= `STATE_IDLE;
387
               else next_fsm_state <= `STATE_TRANSFER;
388
            end
389
        endcase
390
     end
391
 
392
   // Outputs of state machine (combinatorial)
393
   always @ (wb_fsm_state or start_toggle or wb_ack_i or wb_err_i or wr_reg)
394
     begin
395
        rdy_sync_en <= 1'b0;
396
        err_en <= 1'b0;
397
        data_o_en <= 1'b0;
398
        wb_cyc_o <= 1'b0;
399
        wb_stb_o <= 1'b0;
400
 
401
        case (wb_fsm_state)
402
          `STATE_IDLE:
403
            begin
404
               if(start_toggle) begin
405
                  wb_cyc_o <= 1'b1;
406
                  wb_stb_o <= 1'b1;
407
                  if(wb_ack_i || wb_err_i) begin
408
                     err_en <= 1'b1;
409
                     rdy_sync_en <= 1'b1;
410
                  end
411
 
412
                  if (wb_ack_i && !wr_reg) begin
413
                     data_o_en <= 1'b1;
414
                  end
415
               end
416
            end
417
 
418
          `STATE_TRANSFER:
419
            begin
420
               wb_cyc_o <= 1'b1;
421
               wb_stb_o <= 1'b1;
422
               if(wb_ack_i) begin
423
                  err_en <= 1'b1;
424
                  data_o_en <= 1'b1;
425
                  rdy_sync_en <= 1'b1;
426
               end
427
               else if (wb_err_i) begin
428
                  err_en <= 1'b1;
429
                  rdy_sync_en <= 1'b1;
430
               end
431
            end
432
        endcase
433
 
434
     end
435
 
436
endmodule
437
 

powered by: WebSVN 2.1.0

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