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

Subversion Repositories adv_debug_sys

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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