v64x32wrap.v
10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
// v64x32wrap.v v1 Frank Berndt
// wrapper around virage 64x32 modules, 2kbits;
// :set tabstop=4
// output enables of virage sram are not used;
// read data come out of novea and hit ff in mi;
// serial mode is not implemented;
`timescale 1ns/1ns
module v64x32wrap (
sysclk, reset_l, v_recall, v_tread, v_time,
v_me, v_addr, v_in, v_we, v_out, v_nvout,
v_sclk, v_sme, v_si, v_so,
v_porst, v_vpp
);
// operational ports;
input sysclk; // system clock;
input reset_l; // system reset;
input v_recall; // recall on hard reset;
input v_tread; // read for test enable;
input v_time; // time base, 1us;
input v_me; // enable;
input v_we; // write enable;
input [15:2] v_addr; // address;
input [31:0] v_in; // write data;
output [31:0] v_out; // read data;
output [31:0] v_nvout; // novea read data;
input v_sclk; // serial clock;
input v_sme; // serial mode control;
input v_si; // serial input;
output v_so; // serial output;
output v_porst; // power-on reset;
output v_vpp; // only for monitor pad;
// decode the major sub address spaces;
// read data mux controls;
wire v_sram; // virage sram space;
wire v_reg; // store controller register space;
wire v_ctrl; // control register space;
wire v_acc; // array access;
reg [4:2] v_rega; // register address;
reg [1:0] v_sel; // read mux controls;
assign v_sram = ~v_addr[15]; // sram space;
assign v_reg = (v_addr[15:14] == 2'b10); // store controller space;
assign v_ctrl = (v_addr[15:14] == 2'b11); // bypass and control;
assign v_acc = v_me & v_sram;
always @(posedge sysclk)
begin
v_rega[4:2] <= v_addr[4:2];
v_sel[0] <= v_acc;
v_sel[1] <= v_me & v_reg;
end
// charge pump controls;
wire cp_rst; // charge pump reset;
wire cp_pe; // charge pump enable;
wire cp_vpprange; // charge pump vpp range;
wire [3:0] cp_vppsel; // charge pump vpp select;
wire cp_data; // charge pump unlock data;
wire cp_clke; // charge pump clock enable;
wire cp_porst; // charge pump power-on reset output;
wire cp_unlock; // charge pump unlock status;
// novea array controls;
wire [7:2] nv_addr; // novea array address;
wire nv_me; // novea sram enable;
wire nv_we; // novea write enable;
wire nv_recall; // novea recall control;
wire nv_store; // novea store control;
wire nv_comp; // comparator control;
wire [1:0] nv_mrcl; // noveal margin recall control;
wire [1:0] nv_tecc; // noveal cell select control;
wire [1:0] nv_bias; // noveal bias control;
wire nv_match; // novea match output;
wire nv_rcready; // novea recall ready output;
wire [31:0] nv_q; // novea read data;
assign nv_me = v_acc | v_tread;
// virage store controller;
wire nms_ra; // parallel register access;
wire nms_pae; // parallel command enable;
wire nms_we; // nms novea write enable;
wire nms_ready; // nms is ready;
wire nms_pass; // nms command passed;
wire nms_keep; // nms in keep mode;
wire nms_rst; // nms cp reset;
wire nms_pe; // nms cp enable;
wire nms_data; // nms cp data;
wire nms_clke; // nms cp clock enable;
wire nms_vpprange; // nms cp vpp range;
wire [3:0] nms_vppsel; // nms cp vpp select;
wire nms_recall; // nms recall;
wire nms_store; // nms store;
wire nms_comp; // nms comparator control;
wire [1:0] nms_mrcl; // nms margin recall control;
wire [1:0] nms_tecc; // nms cell select control;
wire [1:0] nms_bias; // nms bias control;
wire [31:0] nms_q; // nms read data;
assign nms_ra = v_me & v_reg;
// virage control register;
// controls usage of store controller or direct cpu interface;
reg v_reset; // delayed reset;
wire vctrl_we; // write to virage ctrl register;
reg nms_byp; // bypass virage store controller;
reg vnms_ready; // registered nms ready output;
reg vnms_pass; // registered nms pass output;
reg vnms_keep; // registered nms keep output;
reg [2:0] nms_cmd; // nms command;
reg vnv_rcready; // registered nv recall ready output;
reg vnv_match; // registered nv match output;
reg vnv_recall; // nv recall control;
reg vnv_store; // nv store control;
reg vnv_comp; // nv comp control;
reg [1:0] vnv_mrcl; // nv margin recall controls;
reg [1:0] vnv_tecc; // nv cell seelcts;
reg [1:0] vnv_bias; // nv bias controls;
reg vcp_rst; // cp reset;
reg vcp_pe; // cp enable;
reg vcp_data; // cp unlock data stream;
reg vcp_vpprange; // cp vpp range;
reg [3:0] vcp_vppsel; // cp vpp selects;
reg vcp_unlock; // cp unlock status;
reg vcp_clke; // cp clock enable;
reg [1:0] v_exec; // execute nms command;
assign vctrl_we = v_me & v_we & v_ctrl;
always @(posedge sysclk)
begin
v_reset <= reset_l;
if(v_reset == 1'b0) begin
nms_byp <= 1'b1;
nms_cmd <= 3'd0;
vnv_recall <= v_recall;
vnv_store <= 1'b0;
vnv_comp <= 1'b0;
vnv_mrcl <= 2'd0;
vnv_tecc <= 2'd0;
vnv_bias <= 2'b01;
vcp_rst <= 1'b1;
vcp_pe <= 1'b0;
vcp_data <= 1'b0;
vcp_vpprange <= 1'b0;
vcp_vppsel <= 4'b0;
end else if(vctrl_we) begin
nms_byp <= v_in[31];
nms_cmd <= v_in[26:24];
vnv_recall <= v_in[21];
vnv_store <= v_in[20];
vnv_comp <= v_in[18];
vnv_mrcl <= v_in[17:16];
vnv_tecc <= v_in[15:14];
vnv_bias <= v_in[13:12];
vcp_rst <= v_in[11];
vcp_pe <= v_in[10];
vcp_data <= v_in[9];
vcp_vpprange <= v_in[8];
vcp_vppsel <= v_in[7:4];
end
vnms_ready <= nms_ready;
vnms_pass <= nms_pass;
vnms_keep <= nms_keep;
vnv_rcready <= nv_rcready;
vnv_match <= nv_match;
vcp_unlock <= cp_unlock;
vcp_clke <= vctrl_we & v_addr[12];
v_exec <= {2{v_reset}} & { v_exec[0], vctrl_we & v_addr[13] };
end
assign nms_pae = ~nms_byp & |v_exec;
// sum up read data bits;
wire [31:0] vctrl_out;
assign vctrl_out = {
nms_byp, vnms_ready, vnms_pass, vnms_keep, 1'b0, nms_cmd,
vnv_rcready, vnv_match, nv_recall, nv_store, 1'b0, nv_comp, nv_mrcl,
nv_tecc, nv_bias, cp_rst, cp_pe, cp_data, cp_vpprange,
cp_vppsel, 2'b0, vcp_unlock, cp_porst };
assign v_porst = cp_porst;
// bypass virage store controller;
assign cp_rst = nms_byp? vcp_rst : nms_rst;
assign cp_pe = nms_byp? vcp_pe : nms_pe;
assign cp_data = nms_byp? vcp_data : nms_data;
assign cp_clke = nms_byp? vcp_clke : nms_clke;
assign cp_vpprange = nms_byp? vcp_vpprange : nms_vpprange;
assign cp_vppsel = nms_byp? vcp_vppsel : nms_vppsel;
assign nv_addr = {6{v_tread}} | v_addr[7:2];
assign nv_we = nms_byp? (v_we & ~v_tread) : nms_we;
assign nv_recall = nms_byp? vnv_recall : nms_recall;
assign nv_store = nms_byp? vnv_store : nms_store;
assign nv_comp = nms_byp? vnv_comp : nms_comp;
assign nv_mrcl = nms_byp? vnv_mrcl : nms_mrcl;
assign nv_tecc = nms_byp? vnv_tecc : nms_tecc;
assign nv_bias = nms_byp? vnv_bias : nms_bias;
// instantiate NEC super cell;
// contains charge pump and novea array;
// drive test bus signals inactive;
wire [21:0] nv_tbi; // test bus inputs;
wire [4:0] nv_tbo; // test bus outputs;
wire nv_test; // test mode;
wire nv_bunri; // test mode;
assign nv_tbi = 21'd0;
assign nv_test = 1'b0;
assign nv_bunri = 1'b0;
nms_sc_64x32 vsc (
.CLK(sysclk),
.RST(cp_rst),
.PE(cp_pe),
.VPPRANGE(cp_vpprange),
.VPPSEL3(cp_vppsel[3]),
.VPPSEL2(cp_vppsel[2]),
.VPPSEL1(cp_vppsel[1]),
.VPPSEL0(cp_vppsel[0]),
.D(cp_data),
.CLKE(cp_clke),
.STORE(nv_store),
.VPP(v_vpp),
.PORST(cp_porst),
.UNLOCK(cp_unlock),
.ADR5(nv_addr[7]),
.ADR4(nv_addr[6]),
.ADR3(nv_addr[5]),
.ADR2(nv_addr[4]),
.ADR1(nv_addr[3]),
.ADR0(nv_addr[2]),
.D31(v_in[31]),
.D30(v_in[30]),
.D29(v_in[29]),
.D28(v_in[28]),
.D27(v_in[27]),
.D26(v_in[26]),
.D25(v_in[25]),
.D24(v_in[24]),
.D23(v_in[23]),
.D22(v_in[22]),
.D21(v_in[21]),
.D20(v_in[20]),
.D19(v_in[19]),
.D18(v_in[18]),
.D17(v_in[17]),
.D16(v_in[16]),
.D15(v_in[15]),
.D14(v_in[14]),
.D13(v_in[13]),
.D12(v_in[12]),
.D11(v_in[11]),
.D10(v_in[10]),
.D9(v_in[9]),
.D8(v_in[8]),
.D7(v_in[7]),
.D6(v_in[6]),
.D5(v_in[5]),
.D4(v_in[4]),
.D3(v_in[3]),
.D2(v_in[2]),
.D1(v_in[1]),
.D0(v_in[0]),
.ME(nv_me),
.WE(nv_we),
.SI(v_si),
.SME(v_sme),
.SCLK(v_sclk),
.SO(v_so),
.RECALL(nv_recall),
.COMP(nv_comp),
.MRCL0(nv_mrcl[0]),
.MRCL1(nv_mrcl[1]),
.TECC0(nv_tecc[0]),
.TECC1(nv_tecc[1]),
.BIAS0(nv_bias[0]),
.BIAS1(nv_bias[1]),
.Q31(nv_q[31]),
.Q30(nv_q[30]),
.Q29(nv_q[29]),
.Q28(nv_q[28]),
.Q27(nv_q[27]),
.Q26(nv_q[26]),
.Q25(nv_q[25]),
.Q24(nv_q[24]),
.Q23(nv_q[23]),
.Q22(nv_q[22]),
.Q21(nv_q[21]),
.Q20(nv_q[20]),
.Q19(nv_q[19]),
.Q18(nv_q[18]),
.Q17(nv_q[17]),
.Q16(nv_q[16]),
.Q15(nv_q[15]),
.Q14(nv_q[14]),
.Q13(nv_q[13]),
.Q12(nv_q[12]),
.Q11(nv_q[11]),
.Q10(nv_q[10]),
.Q9(nv_q[9]),
.Q8(nv_q[8]),
.Q7(nv_q[7]),
.Q6(nv_q[6]),
.Q5(nv_q[5]),
.Q4(nv_q[4]),
.Q3(nv_q[3]),
.Q2(nv_q[2]),
.Q1(nv_q[1]),
.Q0(nv_q[0]),
.MATCH(nv_match),
.RCREADY(nv_rcready),
.TEST(nv_test),
.BUNRI(nv_bunri),
.TBI21(nv_tbi[21]),
.TBI20(nv_tbi[20]),
.TBI19(nv_tbi[19]),
.TBI18(nv_tbi[18]),
.TBI17(nv_tbi[17]),
.TBI16(nv_tbi[16]),
.TBI15(nv_tbi[15]),
.TBI14(nv_tbi[14]),
.TBI13(nv_tbi[13]),
.TBI12(nv_tbi[12]),
.TBI11(nv_tbi[11]),
.TBI10(nv_tbi[10]),
.TBI9(nv_tbi[9]),
.TBI8(nv_tbi[8]),
.TBI7(nv_tbi[7]),
.TBI6(nv_tbi[6]),
.TBI5(nv_tbi[5]),
.TBI4(nv_tbi[4]),
.TBI3(nv_tbi[3]),
.TBI2(nv_tbi[2]),
.TBI1(nv_tbi[1]),
.TBI0(nv_tbi[0]),
.TBO4(nv_tbo[4]),
.TBO3(nv_tbo[3]),
.TBO2(nv_tbo[2]),
.TBO1(nv_tbo[1]),
.TBO0(nv_tbo[0])
);
// instantiate store controller;
// can be bypassed if it does not work;
wire nms_wrck; // serial clock;
wire nms_wsi; // serial data input;
wire nms_updatewr;
wire nms_shiftwr;
wire nms_selectwir;
assign nms_wrck = 1'b0;
assign nms_wsi = 1'b0;
assign nms_updatewr = 1'b0;
assign nms_shiftwr = 1'b0;
assign nms_selectwir = 1'b0;
nvco_nc15gfh_64x32 nms (
.SYS_CK(sysclk),
.TIME_B(v_time),
.WRSTN(reset_l),
.WRCK(nms_wrck),
.WSI(nms_wsi),
.UpdateWR(nms_updatewr),
.ShiftWR(nms_shiftwr),
.SelectWIR(nms_selectwir),
.PAE_p(nms_pae),
.PA_p(nms_cmd),
.RCREADY(nv_rcready),
.SO_NV(v_so),
.MATCH(nv_match),
.UNLOCK(cp_unlock),
.PORST(cp_porst),
.ADR_p({ 3'd0, v_rega }),
.D_p(v_in),
.RA_p(nms_ra),
.WE_p(v_we),
.ME_p(v_me),
.OE_p(1'b1),
.WSO(),
.NMS_READY(nms_ready),
.NMS_PASS(nms_pass),
.KEEP_ON(nms_keep),
.RST_i(nms_rst),
.PE(nms_pe),
.VPPRANGE(nms_vpprange),
.VPPSEL(nms_vppsel),
.UDATA(nms_data),
.PCLKE(nms_clke),
.SI_NV(),
.SME_NV(),
.STORE(nms_store),
.COMP(nms_comp),
.RECALL(nms_recall),
.MRCL0(nms_mrcl[0]),
.MRCL1(nms_mrcl[1]),
.TECC0(nms_tecc[0]),
.TECC1(nms_tecc[1]),
.BIAS0(nms_bias[0]),
.BIAS1(nms_bias[1]),
.Q(nms_q),
.WE_NV(nms_we),
.OE_NV(),
.ME_NV(),
.CLK(),
.SCLK_NV(),
.ADR_NV(),
.D_NV()
);
// read data mux;
// select array data, ctrl register or nms reagister data;
assign v_nvout = nv_q;
assign v_out = v_sel[0]? nv_q : v_sel[1]? { 24'd0, nms_q[7:0] } : vctrl_out;
endmodule