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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [tags/] [ADS_RELEASE_1_0_0/] [Hardware/] [adv_dbg_if/] [rtl/] [verilog/] [adbg_wb_biu.v] - Blame information for rev 12

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

powered by: WebSVN 2.1.0

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