20
20
/**
21
21
@brief JTAG stuff for an XC2C-series device
22
22
*/
23
- module XC2CJTAG (tdi, tms, tck, tdo, debug_led, debug_gpio);
23
+ module XC2CJTAG (
24
+ tdi, tms, tck, tdo,
25
+ config_erase,
26
+ config_read_addr, config_read_data,
27
+
28
+ debug_led, debug_gpio);
24
29
25
30
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
31
// Device configuration
@@ -29,6 +34,10 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
29
34
30
35
parameter PACKAGE = "QFG32" ; // Package code (lead-free G assumed)
31
36
37
+ parameter SHREG_WIDTH = 1 ; // ISC shift register width
38
+
39
+ parameter ADDR_BITS = 1 ; // Bits in ISC address shift register
40
+
32
41
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33
42
// I/Os
34
43
@@ -37,6 +46,12 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
37
46
input wire tck;
38
47
output reg tdo;
39
48
49
+ // Status signals to the configuration memory
50
+ output reg config_erase = 0 ; // Erases all config memory
51
+ // This takes 100 ms IRL but for now we'll model it instantly
52
+ output reg [ADDR_BITS- 1 :0 ] config_read_addr = 0 ; // Address for reading the bitstream (real, not gray code)
53
+ input wire [SHREG_WIDTH- 1 :0 ] config_read_data;
54
+
40
55
output reg [3 :0 ] debug_led = 0 ;
41
56
output reg [7 :0 ] debug_gpio = 0 ;
42
57
@@ -219,6 +234,8 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
219
234
// Instruction loading and capture
220
235
always @(posedge tck) begin
221
236
237
+ config_erase <= 0 ;
238
+
222
239
case (state)
223
240
224
241
// Reset instruction to IDCODE upon reset
@@ -243,7 +260,23 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
243
260
244
261
// Done, save the new IR
245
262
STATE_UPDATE_IR: begin
246
- ir <= ir_shreg;
263
+ ir <= ir_shreg;
264
+
265
+ // If we're entering/exiting ISC mode, set the ISC bits appropriately
266
+ // TODO: support OTF mode
267
+ if (ir_shreg == INST_ISC_ENABLE)
268
+ isc_enabled <= 1 ;
269
+ if (ir_shreg == INST_ISC_DISABLE)
270
+ isc_enabled <= 0 ;
271
+
272
+ // Wipe config memory when we get an ERASE instruction
273
+ if (ir_shreg == INST_ISC_ERASE) begin
274
+ config_erase <= 1 ;
275
+ configured <= 0 ;
276
+ end
277
+
278
+ // TODO: copy EEPROM to RAM when we get an ISC_INIT command
279
+
247
280
end // end STATE_UPDATE_IR
248
281
249
282
endcase
@@ -400,7 +433,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
400
433
idcode_shreg <= idcode;
401
434
end // end STATE_CAPTURE_DR
402
435
403
- // Loading a new IR
436
+ // Read the IDCODE
404
437
STATE_SHIFT_DR: begin
405
438
idcode_shreg <= {tdi, idcode_shreg[31 :1 ]};
406
439
end // end STATE_SHIFT_DR
@@ -411,6 +444,49 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
411
444
412
445
end
413
446
447
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
448
+ // Config memory read
449
+
450
+ reg [SHREG_WIDTH- 1 :0 ] isc_read_shreg = 0 ;
451
+
452
+ // New value for the read shreg
453
+ wire [SHREG_WIDTH- 1 :0 ] isc_read_shreg_adv = {tdi, isc_read_shreg[SHREG_WIDTH- 1 :1 ]};
454
+
455
+ // Gray coded read address: left N bits of the shift register
456
+ wire [ADDR_BITS- 1 :0 ] isc_read_addr_gray = isc_read_shreg_adv[SHREG_WIDTH- 1 : SHREG_WIDTH- ADDR_BITS];
457
+
458
+ // Convert Gray code to normal
459
+ reg [ADDR_BITS- 1 :0 ] isc_read_addr_normal;
460
+ integer i;
461
+ always @(* ) begin
462
+ isc_read_addr_normal[ADDR_BITS- 1 ] <= isc_read_addr_gray[ADDR_BITS- 1 ];
463
+ for (i= ADDR_BITS- 2 ; i>= 0 ; i= i- 1 )
464
+ isc_read_addr_normal[i] <= isc_read_addr_gray[i] ^ isc_read_addr_normal[i+ 1 ];
465
+ end
466
+
467
+ always @(posedge tck) begin
468
+
469
+ case (state)
470
+
471
+ // Load the data that we read
472
+ STATE_CAPTURE_DR: begin
473
+ isc_read_shreg <= config_read_data;
474
+ end // end STATE_CAPTURE_DR
475
+
476
+ // Actual readout happens here
477
+ STATE_SHIFT_DR: begin
478
+ isc_read_shreg <= isc_read_shreg_adv;
479
+ end // end STATE_SHIFT_DR
480
+
481
+ // Update: save the de-Gray-ified read address
482
+ STATE_UPDATE_DR: begin
483
+ config_read_addr <= isc_read_addr_normal;
484
+ end // end STATE_UPDATE_DR
485
+
486
+ endcase
487
+
488
+ end
489
+
414
490
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
415
491
// TDO muxing
416
492
@@ -427,6 +503,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
427
503
case (ir)
428
504
INST_BYPASS: tdo <= bypass_shreg;
429
505
INST_IDCODE: tdo <= idcode_shreg[0 ];
506
+ INST_ISC_READ: tdo <= isc_read_shreg[0 ];
430
507
endcase
431
508
end
432
509
@@ -439,7 +516,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
439
516
// 7:0 = pmod_c[3:0]
440
517
always @(* ) begin
441
518
debug_gpio <= 0 ;
442
- debug_gpio[0 ] <= (ir == INST_IDCODE );
519
+ debug_gpio[0 ] <= (ir == INST_ISC_READ );
443
520
debug_gpio[1 ] <= (ir == INST_BYPASS);
444
521
end
445
522
0 commit comments