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

Subversion Repositories socgen

[/] [socgen/] [trunk/] [Projects/] [opencores.org/] [adv_debug_sys/] [Hardware/] [adv_dbg_if/] [rtl/] [verilog/] [adbg_jsp_biu.v] - Blame information for rev 131

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 131 jt_eaton
//////////////////////////////////////////////////////////////////////
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 `VARIANT`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
   `VARIANT`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
   `VARIANT`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
   `VARIANT`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
   `VARIANT`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
   `VARIANT`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
   `VARIANT`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
          default:
425
            begin
426
             wda_rst = 1'b0;
427
        wpp = 1'b0;
428
        w_fifo_en = 1'b0;
429
        w_wb_ack = 1'b0;
430
 
431
 
432
 
433
            end
434
 
435
 
436
 
437
        endcase
438
 
439
     end
440
 
441
   ////////////////////////////////////////////////////////////
442
   // WishBone interface hardware
443
   // Interface signals to read and write fifos:
444
   // wb_rd:  read strobe
445
   // wb_wr:  write strobe
446
   // wb_fifo_ack: fifo has completed operation
447
 
448
   wire [31:0] bus_data_lo;
449
   wire [31:0] bus_data_hi;
450
   wire        wb_reg_ack;
451
   wire        rd_fifo_not_full;  // "rd fifo" is the one the WB writes to
452
   reg [2:0]   iir_gen;  // actually combinatorial
453
   wire        rd_fifo_becoming_empty;
454
 
455
   // These 16550 registers are at least partly implemented
456
   reg         reg_dlab_bit;  // part of the LCR
457
   reg [3:0]   reg_ier;
458
   wire [2:0]  reg_iir;
459
   reg         thr_int_arm;  // used so that an IIR read can clear a transmit interrupt
460
   wire [7:0]  reg_lsr;
461
   wire        reg_dlab_bit_wren;
462
   wire        reg_ier_wren;
463
   wire        reg_iir_rden;
464
   wire [7:0]  reg_lcr;  // the DLAB bit above is the 8th bit
465
   wire        reg_fcr_wren;  // FCR is WR-only, at the same address as the IIR (contains SW reset bits)
466
 
467
   // These 16550 registers are not implemented here
468
   wire [7:0]  reg_mcr;
469
   wire [7:0]  reg_msr;
470
   wire [7:0]  reg_scr;
471
 
472
   // Create handshake signals to/from the FIFOs
473
   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);
474
   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);
475
   assign      wb_ack_o = wb_fifo_ack | wb_reg_ack;
476
   assign      wb_err_o = 1'b0;
477
 
478
   // Assign the unimplemented registers
479
   assign      reg_mcr = 8'h00;  // These bits control modem control lines, unused here
480
   assign      reg_msr = 8'hB0;  // CD, DSR, CTS true, RI false, no changes indicated
481
   assign      reg_scr = 8'h00;  // scratch register.
482
 
483
  // Create the simple / combinatorial registers
484
   assign      rd_fifo_not_full = !(rd_bytes_avail == 4'h8);
485
   assign      reg_lcr = {reg_dlab_bit, 7'h03};  // Always set for 8n1
486
   assign      reg_lsr = {1'b0, rd_fifo_not_full, rd_fifo_not_full, 4'b0000, wr_fifo_not_empty};
487
 
488
   // Create enable bits for the 16550 registers that we actually implement
489
   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);
490
   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);
491
   assign      reg_iir_rden = wb_cyc_i & wb_stb_i & (~wb_we_i) & wb_sel_i[1] & (wb_adr_i[2:0] == 3'b010);
492
   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));
493
   assign      reg_fcr_wren = wb_cyc_i & wb_stb_i & wb_we_i & wb_sel_i[1] & (wb_adr_i[2:0] == 3'b010);
494
   assign      rcvr_fifo_rst = reg_fcr_wren & wb_dat_i[9];
495
   assign      xmit_fifo_rst = reg_fcr_wren & wb_dat_i[10];
496
 
497
   // Create DLAB bit
498
   always @ (posedge wb_clk_i)
499
     begin
500
        if(wb_rst_i) reg_dlab_bit <= 1'b0;
501
        else if(reg_dlab_bit_wren) reg_dlab_bit <= wb_dat_i[7];
502
     end
503
 
504
   // Create IER.  We only use the two LS bits...
505
   always @ (posedge wb_clk_i)
506
     begin
507
        if(wb_rst_i) reg_ier <= 4'h0;
508
        else if(reg_ier_wren) reg_ier <= wb_dat_i[19:16];
509
     end
510
 
511
   // Create IIR (and THR INT arm bit)
512
   assign rd_fifo_becoming_empty = r_fifo_en & (~rpp) & (rd_bytes_avail == 4'h1);  // "rd fifo" is the WB write FIFO...
513
 
514
   always @ (posedge wb_clk_i)
515
     begin
516
        if(wb_rst_i) thr_int_arm <= 1'b0;
517
        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
518
        else if(reg_iir_rden & (~wr_fifo_not_empty)) thr_int_arm <= 1'b0;
519
     end
520
 
521
   always @ (thr_int_arm or rd_fifo_not_full or wr_fifo_not_empty)
522
     begin
523
        if(wr_fifo_not_empty) iir_gen = 3'b100;
524
        else if(thr_int_arm & rd_fifo_not_full) iir_gen = 3'b010;
525
        else iir_gen = 3'b001;
526
     end
527
 
528
   assign reg_iir = iir_gen;
529
 
530
   // Create the data lines out to the WB.
531
   // Always put all 4 bytes on the WB data lines, let the master pick out what it
532
   // wants.   
533
   assign bus_data_lo = {data_to_wb, {4'b0000, reg_ier}, {5'b00000, reg_iir}, reg_lcr};
534
   assign bus_data_hi = {reg_mcr, reg_lsr, reg_msr, reg_scr};
535
   assign wb_dat_o = (wb_adr_i[2]) ? bus_data_hi : bus_data_lo;
536
 
537
   assign data_from_wb = wb_dat_i[31:24];  // Data to the FIFO
538
 
539
   // Generate interrupt output
540
   assign int_o = (rd_fifo_not_full & thr_int_arm & reg_ier[1]) | (wr_fifo_not_empty & reg_ier[0]);
541
 
542
endmodule
543
 

powered by: WebSVN 2.1.0

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