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