Skip to content

Commit ba95711

Browse files
committedJun 14, 2017
Continued XC2CDevice model. Can now enumerate the device, read the ID code/instruction capture state, erase, and read back. Next up, programming
1 parent 216ad0e commit ba95711

File tree

2 files changed

+127
-6
lines changed

2 files changed

+127
-6
lines changed
 

Diff for: ‎hdl/xc2c-model/XC2CDevice.v

+46-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,24 @@ module XC2CDevice(
6565
end
6666
endfunction
6767

68+
function integer ConfigMemoryAbits;
69+
input[15:0] cells;
70+
begin
71+
case(cells)
72+
32: ConfigMemoryAbits = 6;
73+
64: ConfigMemoryAbits = 7;
74+
128: ConfigMemoryAbits = 7;
75+
256: ConfigMemoryAbits = 7;
76+
384: ConfigMemoryAbits = 7;
77+
512: ConfigMemoryAbits = 8;
78+
default: ConfigMemoryAbits = 0;
79+
endcase
80+
end
81+
endfunction
82+
6883
localparam SHREG_WIDTH = ConfigMemoryWidth(MACROCELLS);
6984
localparam MEM_DEPTH = ConfigMemoryDepth(MACROCELLS);
85+
localparam ADDR_BITS = ConfigMemoryAbits(MACROCELLS);
7086

7187
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7288
// Sanity checks
@@ -108,7 +124,8 @@ module XC2CDevice(
108124
integer i;
109125
initial begin
110126
for(i=0; i<MEM_DEPTH; i=i+1)
111-
ram_bitstream[i] <= {SHREG_WIDTH{1'b1}}; //copied from blank EEPROM = all 1s
127+
//ram_bitstream[i] <= {SHREG_WIDTH{1'b1}}; //copied from blank EEPROM = all 1s
128+
ram_bitstream[i] <= {SHREG_WIDTH{1'b0}}; //default initial value
112129
end
113130

114131
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -119,19 +136,46 @@ module XC2CDevice(
119136
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
120137
// JTAG stuff
121138

139+
wire config_erase;
140+
wire[ADDR_BITS-1:0] config_read_addr;
141+
reg[SHREG_WIDTH-1:0] config_read_data = 0;
142+
143+
//Read the EEPROM
144+
//TODO: add read enable?
145+
always @(posedge jtag_tck) begin
146+
config_read_data <= ram_bitstream[config_read_addr];
147+
end
148+
122149
XC2CJTAG #(
123150
.MACROCELLS(MACROCELLS),
124-
.PACKAGE(PACKAGE)
151+
.PACKAGE(PACKAGE),
152+
.SHREG_WIDTH(SHREG_WIDTH),
153+
.ADDR_BITS(ADDR_BITS)
125154
) jtag (
126155
.tdi(jtag_tdi),
127156
.tdo(jtag_tdo),
128157
.tms(jtag_tms),
129158
.tck(jtag_tck),
130159

160+
.config_erase(config_erase),
161+
.config_read_addr(config_read_addr),
162+
.config_read_data(config_read_data),
163+
131164
.debug_led(debug_led),
132165
.debug_gpio(debug_gpio)
133166
);
134167

168+
always @(posedge jtag_tck) begin
169+
170+
//Wipe the config memory when asked
171+
//TODO: pipeline this or are we OK in one cycle?
172+
if(config_erase) begin
173+
for(i=0; i<MEM_DEPTH; i=i+1)
174+
ram_bitstream[i] <= {SHREG_WIDTH{1'b1}};
175+
end
176+
177+
end
178+
135179
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
136180
// The actual CPLD function blocks
137181

Diff for: ‎hdl/xc2c-model/XC2CJTAG.v

+81-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020
/**
2121
@brief JTAG stuff for an XC2C-series device
2222
*/
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);
2429

2530
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2631
// Device configuration
@@ -29,6 +34,10 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
2934

3035
parameter PACKAGE = "QFG32"; //Package code (lead-free G assumed)
3136

37+
parameter SHREG_WIDTH = 1; //ISC shift register width
38+
39+
parameter ADDR_BITS = 1; //Bits in ISC address shift register
40+
3241
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3342
// I/Os
3443

@@ -37,6 +46,12 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
3746
input wire tck;
3847
output reg tdo;
3948

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+
4055
output reg[3:0] debug_led = 0;
4156
output reg[7:0] debug_gpio = 0;
4257

@@ -219,6 +234,8 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
219234
//Instruction loading and capture
220235
always @(posedge tck) begin
221236

237+
config_erase <= 0;
238+
222239
case(state)
223240

224241
//Reset instruction to IDCODE upon reset
@@ -243,7 +260,23 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
243260

244261
//Done, save the new IR
245262
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+
247280
end //end STATE_UPDATE_IR
248281

249282
endcase
@@ -400,7 +433,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
400433
idcode_shreg <= idcode;
401434
end //end STATE_CAPTURE_DR
402435

403-
//Loading a new IR
436+
//Read the IDCODE
404437
STATE_SHIFT_DR: begin
405438
idcode_shreg <= {tdi, idcode_shreg[31:1]};
406439
end //end STATE_SHIFT_DR
@@ -411,6 +444,49 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
411444

412445
end
413446

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+
414490
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
415491
// TDO muxing
416492

@@ -427,6 +503,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
427503
case(ir)
428504
INST_BYPASS: tdo <= bypass_shreg;
429505
INST_IDCODE: tdo <= idcode_shreg[0];
506+
INST_ISC_READ: tdo <= isc_read_shreg[0];
430507
endcase
431508
end
432509

@@ -439,7 +516,7 @@ module XC2CJTAG(tdi, tms, tck, tdo, debug_led, debug_gpio);
439516
//7:0 = pmod_c[3:0]
440517
always @(*) begin
441518
debug_gpio <= 0;
442-
debug_gpio[0] <= (ir == INST_IDCODE);
519+
debug_gpio[0] <= (ir == INST_ISC_READ);
443520
debug_gpio[1] <= (ir == INST_BYPASS);
444521
end
445522

0 commit comments

Comments
 (0)
Please sign in to comment.