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_jsp_biu.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 42 nyawn
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  adbg_jsp_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) 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
// This is where the magic happens in the JTAG Serial Port.  The serial
41
// port FIFOs and counters are kept in the WishBone clock domain.
42
// 'Syncflop' elements are used to synchronize strobe lines across
43
// clock domains, and 'syncreg' elements keep the byte and free count
44
// as current as possible in the JTAG clock domain.  Also in the WB
45
// clock domain is a WishBone target interface, which more or less
46
// tries to emulate a 16550 without FIFOs (despite the fact that
47
// FIFOs are actually present, they are opaque to the WB interface.)
48
//
49
 
50
 
51
// Top module
52
module adbg_jsp_biu
53
  (
54
   // Debug interface signals
55
   tck_i,
56
   rst_i,
57
   data_i,
58
   data_o,
59
   bytes_available_o,
60
   bytes_free_o,
61
   rd_strobe_i,
62
   wr_strobe_i,
63
 
64
   // Wishbone signals
65
   wb_clk_i,
66
   wb_rst_i,
67
   wb_adr_i,
68
   wb_dat_o,
69
   wb_dat_i,
70
   wb_cyc_i,
71
   wb_stb_i,
72
   wb_sel_i,
73
   wb_we_i,
74
   wb_ack_o,
75
   wb_cab_i,
76
   wb_err_o,
77
   wb_cti_i,
78
   wb_bte_i,
79
   int_o
80
   );
81
 
82
   // Debug interface signals
83
   input tck_i;
84
   input rst_i;
85
   input [7:0] data_i;  // Assume short words are in UPPER order bits!
86
   output [7:0] data_o;
87
   output [3:0] bytes_free_o;
88
   output [3:0] bytes_available_o;
89
   input        rd_strobe_i;
90
   input        wr_strobe_i;
91
 
92
   // Wishbone signals
93
   input         wb_clk_i;
94
   input         wb_rst_i;
95
   input  [31:0] wb_adr_i;
96
   output [31:0] wb_dat_o;
97
   input  [31:0] wb_dat_i;
98
   input         wb_cyc_i;
99
   input         wb_stb_i;
100
   input  [3:0]  wb_sel_i;
101
   input         wb_we_i;
102
   output        wb_ack_o;
103
   input         wb_cab_i;
104
   output        wb_err_o;
105
   input  [2:0]  wb_cti_i;
106
   input  [1:0]  wb_bte_i;
107
   output        int_o;
108
 
109
   wire          wb_ack_o;
110
   wire [31:0]    wb_dat_o;
111
   wire          wb_err_o;
112
   wire          int_o;
113
 
114
   wire [7:0]     data_o;
115
   wire [3:0]     bytes_free_o;
116
   wire [3:0]     bytes_available_o;
117
 
118
   // Registers
119
   reg [7:0]      data_in;
120
   reg [7:0]      rdata;
121
   reg           wen_tff;
122
   reg           ren_tff;
123
 
124
   // Wires  
125
   wire          wb_fifo_ack;
126
   wire [3:0]     wr_bytes_free;
127
   wire [3:0]     rd_bytes_avail;
128
   wire [3:0]     wr_bytes_avail;  // used to generate wr_fifo_not_empty
129
   wire          rd_bytes_avail_not_zero;
130
   wire          ren_sff_out;
131
   wire [7:0]     rd_fifo_data_out;
132
   wire [7:0]     data_to_wb;
133
   wire [7:0]     data_from_wb;
134
   wire          wr_fifo_not_empty;  // this is for the WishBone interface LSR register
135
   wire        rcvr_fifo_rst;  // rcvr in the WB sense, opposite most of the rest of this file
136
   wire        xmit_fifo_rst;  // ditto
137
 
138
   // Control Signals (FSM outputs)
139
   reg           wda_rst;   // reset wdata_avail SFF
140
   reg           wpp;       // Write FIFO PUSH (1) or POP (0)
141
   reg           w_fifo_en; // Enable write FIFO
142
   reg           ren_rst;   // reset 'pop' SFF
143
   reg           rdata_en;  // enable 'rdata' register
144
   reg           rpp;       // read FIFO PUSH (1) or POP (0)
145
   reg           r_fifo_en; // enable read FIFO    
146
   reg           r_wb_ack;  // read FSM acks WB transaction
147
   reg           w_wb_ack;  // write FSM acks WB transaction
148
 
149
   // Indicators to FSMs
150
   wire          wdata_avail; // JTAG side has data available
151
   wire          wb_rd;       // WishBone requests read
152
   wire          wb_wr;       // WishBone requests write
153
   wire          pop;         // JTAG side received a byte, pop and get next
154
   wire          rcz;         // zero bytes available in read FIFO
155
 
156
 
157
 
158
   //////////////////////////////////////////////////////
159
   // TCK clock domain
160
   // There is no FSM here, just signal latching and clock
161
   // domain synchronization
162
 
163
   assign        data_o = rdata;
164
 
165
   // Write enable (WEN) toggle FF
166
   always @ (posedge tck_i or posedge rst_i)
167
     begin
168
        if(rst_i) wen_tff <= 1'b0;
169
        else if(wr_strobe_i) wen_tff <= ~wen_tff;
170
     end
171
 
172
 
173
   // Read enable (REN) toggle FF
174
   always @ (posedge tck_i or posedge rst_i)
175
     begin
176
        if(rst_i) ren_tff <= 1'b0;
177
        else if(rd_strobe_i) ren_tff <= ~ren_tff;
178
     end
179
 
180
   // Write data register
181
   always @ (posedge tck_i or posedge rst_i)
182
     begin
183
        if(rst_i) data_in <= 8'h0;
184
        else if(wr_strobe_i) data_in <= data_i;
185
     end
186
 
187
 
188
   ///////////////////////////////////////////////////////
189
   // Wishbone clock domain
190
 
191
   // Combinatorial assignments
192
   assign rd_bytes_avail_not_zero = !(rd_bytes_avail == 4'h0);
193
   assign pop = ren_sff_out & rd_bytes_avail_not_zero;
194
   assign rcz = ~rd_bytes_avail_not_zero;
195
   assign wb_fifo_ack = r_wb_ack | w_wb_ack;
196
   assign wr_fifo_not_empty = !(wr_bytes_avail == 4'h0);
197
 
198
   // rdata register
199
   always @ (posedge wb_clk_i or posedge rst_i)
200
     begin
201
        if(rst_i) rdata <= 8'h0;
202
        else if(rdata_en) rdata <= rd_fifo_data_out;
203
     end
204
 
205
   // WEN SFF
206
   syncflop wen_sff (
207
                     .DEST_CLK(wb_clk_i),
208
                     .D_SET(1'b0),
209
                     .D_RST(wda_rst),
210
                     .RESET(rst_i),
211
                     .TOGGLE_IN(wen_tff),
212
                     .D_OUT(wdata_avail)
213
                     );
214
 
215
   // REN SFF
216
   syncflop ren_sff (
217
                     .DEST_CLK(wb_clk_i),
218
                     .D_SET(1'b0),
219
                     .D_RST(ren_rst),
220
                     .RESET(rst_i),
221
                     .TOGGLE_IN(ren_tff),
222
                     .D_OUT(ren_sff_out)
223
                     );
224
 
225
   // 'free space available' syncreg
226
   syncreg freespace_syncreg (
227
                              .CLKA(wb_clk_i),
228
                              .CLKB(tck_i),
229
                              .RST(rst_i),
230
                              .DATA_IN(wr_bytes_free),
231
                              .DATA_OUT(bytes_free_o)
232
                              );
233
 
234
   // 'bytes available' syncreg
235
   syncreg bytesavail_syncreg (
236
                              .CLKA(wb_clk_i),
237
                              .CLKB(tck_i),
238
                              .RST(rst_i),
239
                              .DATA_IN(rd_bytes_avail),
240
                              .DATA_OUT(bytes_available_o)
241
                              );
242
 
243
   // write FIFO
244
   bytefifo wr_fifo (
245
                     .CLK(wb_clk_i),
246
                     .RST(rst_i | rcvr_fifo_rst),  // rst_i from JTAG clk domain, rcvr_fifo_rst from WB, RST is async reset
247
                     .DATA_IN(data_in),
248
                     .DATA_OUT(data_to_wb),
249
                     .PUSH_POPn(wpp),
250
                     .EN(w_fifo_en),
251
                     .BYTES_AVAIL(wr_bytes_avail),
252
                     .BYTES_FREE(wr_bytes_free)
253
                     );
254
 
255
   // read FIFO
256
   bytefifo rd_fifo (
257
                     .CLK(wb_clk_i),
258
                     .RST(rst_i | xmit_fifo_rst),  // rst_i from JTAG clk domain, xmit_fifo_rst from WB, RST is async reset
259
                     .DATA_IN(data_from_wb),
260
                     .DATA_OUT(rd_fifo_data_out),
261
                     .PUSH_POPn(rpp),
262
                     .EN(r_fifo_en),
263
                     .BYTES_AVAIL(rd_bytes_avail),
264
                     .BYTES_FREE()
265
                     );
266
 
267
   /////////////////////////////////////////////////////
268
   // State machine for the read FIFO
269
 
270
   reg [1:0] rd_fsm_state;
271
   reg [1:0]   next_rd_fsm_state;
272
 
273
`define STATE_RD_IDLE     2'h0
274
`define STATE_RD_PUSH     2'h1
275
`define STATE_RD_POP      2'h2
276
`define STATE_RD_LATCH    2'h3
277
 
278
   // Sequential bit
279
   always @ (posedge wb_clk_i or posedge rst_i)
280
     begin
281
        if(rst_i) rd_fsm_state <= `STATE_RD_IDLE;
282
        else rd_fsm_state <= next_rd_fsm_state;
283
     end
284
 
285
   // Determination of next state (combinatorial)
286
   always @ (rd_fsm_state or wb_wr or pop or rcz)
287
     begin
288
        case (rd_fsm_state)
289
          `STATE_RD_IDLE:
290
            begin
291
               if(wb_wr) next_rd_fsm_state <= `STATE_RD_PUSH;
292
               else if (pop) next_rd_fsm_state <= `STATE_RD_POP;
293
               else next_rd_fsm_state <= `STATE_RD_IDLE;
294
            end
295
          `STATE_RD_PUSH:
296
            begin
297
               if(rcz) next_rd_fsm_state <= `STATE_RD_LATCH;  // putting first item in fifo, move to rdata in state LATCH
298
               else if(pop) next_rd_fsm_state <= `STATE_RD_POP;
299
               else next_rd_fsm_state <= `STATE_RD_IDLE;
300
            end
301
          `STATE_RD_POP:
302
            begin
303
               next_rd_fsm_state <= `STATE_RD_LATCH; // new data at FIFO head, move to rdata in state LATCH
304
            end
305
          `STATE_RD_LATCH:
306
            begin
307
               if(wb_wr) next_rd_fsm_state <= `STATE_RD_PUSH;
308
               else if(pop) next_rd_fsm_state <= `STATE_RD_POP;
309
               else next_rd_fsm_state <= `STATE_RD_IDLE;
310
            end
311
          default:
312
            begin
313
               next_rd_fsm_state <= `STATE_RD_IDLE;
314
            end
315
        endcase
316
     end
317
 
318
   // Outputs of state machine (combinatorial)
319
   always @ (rd_fsm_state)
320
     begin
321
        ren_rst <= 1'b0;
322
        rpp <= 1'b0;
323
        r_fifo_en <= 1'b0;
324
        rdata_en <= 1'b0;
325
        r_wb_ack <= 1'b0;
326
 
327
        case (rd_fsm_state)
328
          `STATE_RD_IDLE:;
329
 
330
          `STATE_RD_PUSH:
331
            begin
332
               rpp <= 1'b1;
333
               r_fifo_en <= 1'b1;
334
               r_wb_ack <= 1'b1;
335
            end
336
 
337
          `STATE_RD_POP:
338
            begin
339
               ren_rst <= 1'b1;
340
               r_fifo_en <= 1'b1;
341
            end
342
 
343
          `STATE_RD_LATCH:
344
            begin
345
               rdata_en <= 1'b1;
346
            end
347
        endcase
348
     end
349
 
350
 
351
   /////////////////////////////////////////////////////
352
   // State machine for the write FIFO
353
 
354
   reg [1:0] wr_fsm_state;
355
   reg [1:0] next_wr_fsm_state;
356
 
357
`define STATE_WR_IDLE     2'h0
358
`define STATE_WR_PUSH     2'h1
359
`define STATE_WR_POP      2'h2
360
 
361
 
362
   // Sequential bit
363
   always @ (posedge wb_clk_i or posedge rst_i)
364
     begin
365
        if(rst_i) wr_fsm_state <= `STATE_WR_IDLE;
366
        else wr_fsm_state <= next_wr_fsm_state;
367
     end
368
 
369
   // Determination of next state (combinatorial)
370
   always @ (wr_fsm_state or wb_rd or wdata_avail)
371
     begin
372
        case (wr_fsm_state)
373
 
374
          `STATE_WR_IDLE:
375
            begin
376
               if(wb_rd) next_wr_fsm_state <= `STATE_WR_POP;
377
               else if (wdata_avail) next_wr_fsm_state <= `STATE_WR_PUSH;
378
               else next_wr_fsm_state <= `STATE_WR_IDLE;
379
            end
380
 
381
          `STATE_WR_PUSH:
382
            begin
383
               if(wb_rd) next_wr_fsm_state <= `STATE_WR_POP;
384
               else next_wr_fsm_state <= `STATE_WR_IDLE;
385
            end
386
 
387
          `STATE_WR_POP:
388
            begin
389
               if(wdata_avail) next_wr_fsm_state <= `STATE_WR_PUSH;
390
               else next_wr_fsm_state <= `STATE_WR_IDLE;
391
            end
392
 
393
          default:
394
            begin
395
               next_wr_fsm_state <= `STATE_WR_IDLE;
396
            end
397
        endcase
398
     end
399
 
400
   // Outputs of state machine (combinatorial)
401
   always @ (wr_fsm_state)
402
     begin
403
        wda_rst <= 1'b0;
404
        wpp <= 1'b0;
405
        w_fifo_en <= 1'b0;
406
        w_wb_ack <= 1'b0;
407
 
408
        case (wr_fsm_state)
409
          `STATE_WR_IDLE:;
410
 
411
          `STATE_WR_PUSH:
412
            begin
413
               wda_rst <= 1'b1;
414
               wpp <= 1'b1;
415
               w_fifo_en <= 1'b1;
416
            end
417
 
418
          `STATE_WR_POP:
419
            begin
420
               w_wb_ack <= 1'b1;
421
               w_fifo_en <= 1'b1;
422
            end
423
 
424
        endcase
425
 
426
     end
427
 
428
   ////////////////////////////////////////////////////////////
429
   // WishBone interface hardware
430
   // Interface signals to read and write fifos:
431
   // wb_rd:  read strobe
432
   // wb_wr:  write strobe
433
   // wb_fifo_ack: fifo has completed operation
434
 
435
   wire [31:0] bus_data_lo;
436
   wire [31:0] bus_data_hi;
437
   wire        wb_reg_ack;
438
   wire        rd_fifo_not_full;  // "rd fifo" is the one the WB writes to
439
   reg [2:0]   iir_gen;  // actually combinatorial
440
   wire        rd_fifo_becoming_empty;
441
 
442
   // These 16550 registers are at least partly implemented
443
   reg         reg_dlab_bit;  // part of the LCR
444
   reg [3:0]   reg_ier;
445
   wire [2:0]  reg_iir;
446
   reg         thr_int_arm;  // used so that an IIR read can clear a transmit interrupt
447
   wire [7:0]  reg_lsr;
448
   wire        reg_dlab_bit_wren;
449
   wire        reg_ier_wren;
450
   wire        reg_iir_rden;
451
   wire [7:0]  reg_lcr;  // the DLAB bit above is the 8th bit
452
   wire        reg_fcr_wren;  // FCR is WR-only, at the same address as the IIR (contains SW reset bits)
453
 
454
   // These 16550 registers are not implemented here
455
   wire [7:0]  reg_mcr;
456
   wire [7:0]  reg_msr;
457
   wire [7:0]  reg_scr;
458
 
459
   // Create handshake signals to/from the FIFOs
460
   assign      wb_rd = wb_cyc_i & wb_stb_i & (~wb_we_i) & wb_sel_i[3] & (wb_adr_i[1:0] == 2'b00) & (~reg_dlab_bit);
461
   assign      wb_wr = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[3] & (wb_adr_i[1:0] == 2'b00) & (~reg_dlab_bit);
462
   assign      wb_ack_o = wb_fifo_ack | wb_reg_ack;
463
   assign      wb_err_o = 1'b0;
464
 
465
   // Assign the unimplemented registers
466
   assign      reg_mcr = 8'h00;  // These bits control modem control lines, unused here
467
   assign      reg_msr = 8'hB0;  // CD, DSR, CTS true, RI false, no changes indicated
468
   assign      reg_scr = 8'h00;  // scratch register.
469
 
470
  // Create the simple / combinatorial registers
471
   assign      rd_fifo_not_full = !(rd_bytes_avail == 4'h8);
472
   assign      reg_lcr = {reg_dlab_bit, 7'h03};  // Always set for 8n1
473
   assign      reg_lsr = {1'b0, rd_fifo_not_full, rd_fifo_not_full, 4'b0000, wr_fifo_not_empty};
474
 
475
   // Create enable bits for the 16550 registers that we actually implement
476
   assign      reg_dlab_bit_wren = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[0] & (wb_adr_i[2:0] == 3'b011);
477
   assign      reg_ier_wren = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[2] & (wb_adr_i[2:0] == 3'b001) & (~reg_dlab_bit);
478
   assign      reg_iir_rden = wb_cyc_i & wb_stb_i & (~wb_we_i) & wb_sel_i[1] & (wb_adr_i[2:0] == 3'b010);
479
   assign      wb_reg_ack = wb_cyc_i & wb_stb_i & (|wb_sel_i[3:0]) & (reg_dlab_bit | (wb_adr_i[2:0] != 3'b000));
480
   assign      reg_fcr_wren = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[1] & (wb_adr_i[2:0] == 3'b010);
481
   assign      rcvr_fifo_rst = reg_fcr_wren & wb_dat_i[9];
482
   assign      xmit_fifo_rst = reg_fcr_wren & wb_dat_i[10];
483
 
484
   // Create DLAB bit
485
   always @ (posedge wb_clk_i)
486
     begin
487
        if(wb_rst_i) reg_dlab_bit <= 1'b0;
488
        else if(reg_dlab_bit_wren) reg_dlab_bit <= wb_dat_i[7];
489
     end
490
 
491
   // Create IER.  We only use the two LS bits...
492
   always @ (posedge wb_clk_i)
493
     begin
494
        if(wb_rst_i) reg_ier <= 4'h0;
495
        else if(reg_ier_wren) reg_ier <= wb_dat_i[19:16];
496
     end
497
 
498
   // Create IIR (and THR INT arm bit)
499
   assign rd_fifo_becoming_empty = r_fifo_en & (~rpp) & (rd_bytes_avail == 4'h1);  // "rd fifo" is the WB write FIFO...
500
 
501
   always @ (posedge wb_clk_i)
502
     begin
503
        if(wb_rst_i) thr_int_arm <= 1'b0;
504
        else if(wb_wr | rd_fifo_becoming_empty) thr_int_arm <= 1'b1;  // Set when WB write fifo becomes empty, or on a write to it
505
        else if(reg_iir_rden & (~wr_fifo_not_empty)) thr_int_arm <= 1'b0;
506
     end
507
 
508
   always @ (thr_int_arm or rd_fifo_not_full or wr_fifo_not_empty)
509
     begin
510
        if(wr_fifo_not_empty) iir_gen <= 3'b100;
511
        else if(thr_int_arm & rd_fifo_not_full) iir_gen <= 3'b010;
512
        else iir_gen <= 3'b001;
513
     end
514
 
515 51 nyawn
   assign reg_iir = iir_gen;
516 42 nyawn
 
517
   // Create the data lines out to the WB.
518
   // Always put all 4 bytes on the WB data lines, let the master pick out what it
519
   // wants.   
520
   assign bus_data_lo = {data_to_wb, {4'b0000, reg_ier}, {5'b00000, reg_iir}, reg_lcr};
521
   assign bus_data_hi = {reg_mcr, reg_lsr, reg_msr, reg_scr};
522
   assign wb_dat_o = (wb_adr_i[2]) ? bus_data_hi : bus_data_lo;
523
 
524
   assign data_from_wb = wb_dat_i[31:24];  // Data to the FIFO
525
 
526
   // Generate interrupt output
527
   assign int_o = (rd_fifo_not_full & thr_int_arm & reg_ier[1]) | (wr_fifo_not_empty & reg_ier[0]);
528
 
529
endmodule
530
 

powered by: WebSVN 2.1.0

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