-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbeta.jsim
442 lines (350 loc) · 12 KB
/
beta.jsim
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
436
437
438
439
440
441
442
.include "nominal.jsim"
.include "stdcell.jsim"
.include "stdalu.jsim"
.include "harness.jsim"
.subckt pc clk reset stall _z pcsel[1:0] jt[31:2] exe_pcr[30:2] pc[31:2] ia[31:2] pc_annul
.connect exe_pcr[31] pc[31] br_pc[31] ia[31]
.connect pc[1:0] 0
.connect ia[1:0] 0
.connect jt[1:0] 0
.connect d[1:0] 0
.connect br_pc[1:0] 0
// buffer z
Xz _z z buffer_8
// increment pc + 4
Xpc4 ia[30:2] ci[29:2] vdd pc[30:2] ci[30:2] incrementer
// reset if need to branch
Xpc z#29 pc[30:2] exe_pcr[30:2] br_pc[30:2] mux2
Xjt31 ia[31] jt[31] _jt31 and2
Xpcsel pcsel[0]#30 pcsel[1]#30
+ br_pc[31:2] // BR / PC4 (0b00)
+ _jt31 jt[30:2] // JT (0b01)
+ vdd 0#27 0 vdd // ILLOP (0b10)
+ vdd 0#27 vdd 0 // XADDR (0b11)
+ __d[31:2] mux4
Xstall stall#30 __d[31:2] ia[31:2] _d[31:2] mux2
Xreset reset#30 _d[31:2] vdd 0#29 d[31:2] mux2
Xregpc d[31:2] clk#30 ia[31:2] dreg
Xannul reset pcsel[1] pcsel[0] z pc_annul or4
.ends
.subckt regfile clk reset werf wasel ra2sel ra[4:0] rb[4:0] rc[4:0] wa_rc[4:0] wdata[31:0] radata[31:0] rbdata[31:0] mem_op[31:26] stall
Xwa wasel#5 wa_rc[4:0] vdd#4 0 wa[4:0] mux2
Xregfile
+ vdd 0 0 ra[4:0] adata[31:0] // A read port
+ vdd 0 0 ra2mux[4:0] bdata[31:0] // B read port
+ 0 clk werf wa[4:0] wdata[31:0] // write port
+ $memory width=32 nlocations=31
Xra2 ra2sel#5 rb[4:0] rc[4:0] ra2mux[4:0] mux2
// bypass logic
Xbypctl reset ra[4:0] ra2mux[4:0] mem_op[31:26] wa_rc[4:0] werf bypa bypb stall bypctl
Xbyfa bypa _bypa buffer_8
Xbyfb bypb _bypb buffer_8
Xbypa _bypa#32 adata[31:0] wdata[31:0] yadata[31:0] mux2
Xbypb _bypb#32 bdata[31:0] wdata[31:0] ybdata[31:0] mux2
Xr31a1 ra[4:3] a1 nand2
Xr31a2 ra[2:0] a2 nand3
Xr31a3 a1 a2 r31a or2 // merge nor2 with subsequent inverter
Xadata yadata[31:0] r31a#32 radata[31:0] and2
Xr31b1 ra2mux[4:3] b1 nand2
Xr31b2 ra2mux[2:0] b2 nand3
Xr31b3 b1 b2 r31b or2 // merge nor2 with subsequent inverter
Xbdata ybdata[31:0] r31b#32 rbdata[31:0] and2
.ends
.subckt cmp5 a[4:0] b[4:0] s
Xcmp0 a[4:0] b[4:0] c[4:0] xor2
Xcmp1 c[4:0] 0 d[1:0] nor3
Xcmp2 d[1:0] s and2
.ends
.subckt cmp5inv a[4:0] b[4:0] s
Xcmp0 a[4:0] b[4:0] c[4:0] xor2
Xcmp1 c[4:0] 0 d[1:0] nor3
Xcmp2 d[1:0] s nand2
.ends
.subckt cmp5n31 a[4:0] s
Xcmp0 a[4:0] vdd d[1:0] and3
Xcmp1 d[1:0] s nand2
.ends
.subckt bypctl reset exe_ra[4:0] exe_rb[4:0] mem_op[31:26] wa_rc[4:0] werf bypa bypb stall
* BYPASS: WERF, Rexe == Rmem != R31
Xcmpawr exe_ra[4:0] wa_rc[4:0] ra_match cmp5
Xcmpbwr exe_rb[4:0] wa_rc[4:0] rb_match cmp5
Xcmpa31 exe_ra[4:0] ra_not31 cmp5n31
Xcmpb31 exe_rb[4:0] rb_not31 cmp5n31
Xabyp werf ra_match ra_not31 _bypa and3
Xbbyp werf rb_match rb_not31 _bypb and3
* STALL: LD (0b011000, 0x18) && (bypa || bypb)
Xld0 mem_op[31] mem_op[28:26] ld0 nor4
Xld1 _bypa _bypb byp_flag or2
Xld2 mem_op[30:29] ld0 byp_flag _stall and4
* reset
Xreset reset#3
+ _bypa _bypb _stall
+ 0 0 0
+ bypa bypb stall
+ mux2
.ends
.subckt exectl irq id[31:26] pcsel[1:0] asel ra2sel bsel alufn[5:0]
* irq flag
Xirq irq#2 _pcsel[1:0] vdd#2 pcsel[1:0] mux2
* RA2SEL: ST (0b011001) = 1 / OP (0b10XXXX) = 0 / OTHER = X (default to 1 for ease)
Xra0 id[30] ra0 inverter
Xra1 id[31] ra0 ra2sel nand2
* ROM
Xctl vdd 0 0 id[31:26] // one read port
+ _pcsel[1:0] asel bsel alufn[5:0]
+ $memory width=10 nlocations=64 contents=(
+ 0b1000000000 // opcode=0b000000
+ 0b1000000000 // opcode=0b000001
+ 0b1000000000 // opcode=0b000010
+ 0b1000000000 // opcode=0b000011
+ 0b1000000000 // opcode=0b000100
+ 0b1000000000 // opcode=0b000101
+ 0b1000000000 // opcode=0b000110
+ 0b1000000000 // opcode=0b000111
+ 0b1000000000 // opcode=0b001000
+ 0b1000000000 // opcode=0b001001
+ 0b1000000000 // opcode=0b001010
+ 0b1000000000 // opcode=0b001011
+ 0b1000000000 // opcode=0b001100
+ 0b1000000000 // opcode=0b001101
+ 0b1000000000 // opcode=0b001110
+ 0b1000000000 // opcode=0b001111
+ 0b1000000000 // opcode=0b010000
+ 0b1000000000 // opcode=0b010001
+ 0b1000000000 // opcode=0b010010
+ 0b1000000000 // opcode=0b010011
+ 0b1000000000 // opcode=0b010100
+ 0b1000000000 // opcode=0b010101
+ 0b1000000000 // opcode=0b010110
+ 0b1000000000 // opcode=0b010111
+ 0b0001000000 // opcode=0b011000 LD
+ 0b0001000000 // opcode=0b011001 ST
+ 0b1000000000 // opcode=0b011010
+ 0b0100000000 // opcode=0b011011 JMP
+ 0b1000000000 // opcode=0b011100
+ 0b0000000000 // opcode=0b011101 BEQ
+ 0b0000000000 // opcode=0b011110 BNE
+ 0b0010011010 // opcode=0b011111 LDR
+ 0b0000000000 // opcode=0b100000 ADD
+ 0b0000000001 // opcode=0b100001 SUB
+ 0b0000000000 // opcode=0b100010 MUL
+ 0b0000000000 // opcode=0b100011 DIV
+ 0b0000110011 // opcode=0b100100 CMPEQ
+ 0b0000110101 // opcode=0b100101 CMPLT
+ 0b0000110111 // opcode=0b100110 CMPLE
+ 0b1000000000 // opcode=0b100111
+ 0b0000011000 // opcode=0b101000 AND
+ 0b0000011110 // opcode=0b101001 OR
+ 0b0000010110 // opcode=0b101010 XOR
+ 0b1000000000 // opcode=0b101011
+ 0b0000100000 // opcode=0b101100 SHL
+ 0b0000100001 // opcode=0b101101 SHR
+ 0b0000100011 // opcode=0b101110 SRA
+ 0b1000000000 // opcode=0b101111
+ 0b0001000000 // opcode=0b110000 ADDC
+ 0b0001000001 // opcode=0b110001 SUBC
+ 0b0001000000 // opcode=0b110010 MULC
+ 0b0001000000 // opcode=0b110011 DIVC
+ 0b0001110011 // opcode=0b110100 CMPEQC
+ 0b0001110101 // opcode=0b110101 CMPLTC
+ 0b0001110111 // opcode=0b110110 CMPLEC
+ 0b1000000000 // opcode=0b110111
+ 0b0001011000 // opcode=0b111000 ANDC
+ 0b0001011110 // opcode=0b111001 ORC
+ 0b0001010110 // opcode=0b111010 XORC
+ 0b1000000000 // opcode=0b111011
+ 0b0001100000 // opcode=0b111100 SHLC
+ 0b0001100001 // opcode=0b111101 SHRC
+ 0b0001100011 // opcode=0b111110 SRAC
+ 0b1000000000 // opcode=0b111111
+ )
.ends
.subckt memctl reset irq id[31:26] wasel wdsel[1:0] werf moe wr
* reset flag
Xwr reset#2
+ xwr xmoe
+ 0 0
+ wr moe
+ mux2
* MOE: LD (0b011000) / LDR (0b011111)
Xldr0 id[31] ldr0 inverter
Xldr1 ldr0 id[30:26] ldr1 ldr2 nand3
Xldr2 ldr1 ldr2 ldr_hit nor2
Xld0 id[31] id[28:26] ld0 nor4
Xld1 ld0 id[30:29] ld1 nand3
Xld2 ld1 ld_hit inverter
Xldldr ld_hit ldr_hit xmoe or2
* irq flag
Xirq irq#5
+ _werf _wdsel[1:0] _wr _wasel
+ vdd 0#2 0 vdd
+ werf wdsel[1:0] xwr wasel
+ mux2
* WR: ST (0b011001) = 1 / OTHER = 0
Xst0 id[31] id[28] id[27] st0 nor3
Xst1 id[30] id[29] id[26] st1 and3
Xst2 st0 st1 _wr and2
* ROM
Xctl vdd 0 0 id[31:26] // one read port
+ _wasel _wdsel[1:0] _werf
+ $memory width=4 nlocations=64 contents=(
+ 0b1001 // opcode=0b000000
+ 0b1001 // opcode=0b000001
+ 0b1001 // opcode=0b000010
+ 0b1001 // opcode=0b000011
+ 0b1001 // opcode=0b000100
+ 0b1001 // opcode=0b000101
+ 0b1001 // opcode=0b000110
+ 0b1001 // opcode=0b000111
+ 0b1001 // opcode=0b001000
+ 0b1001 // opcode=0b001001
+ 0b1001 // opcode=0b001010
+ 0b1001 // opcode=0b001011
+ 0b1001 // opcode=0b001100
+ 0b1001 // opcode=0b001101
+ 0b1001 // opcode=0b001110
+ 0b1001 // opcode=0b001111
+ 0b1001 // opcode=0b010000
+ 0b1001 // opcode=0b010001
+ 0b1001 // opcode=0b010010
+ 0b1001 // opcode=0b010011
+ 0b1001 // opcode=0b010100
+ 0b1001 // opcode=0b010101
+ 0b1001 // opcode=0b010110
+ 0b1001 // opcode=0b010111
+ 0b0101 // opcode=0b011000 LD
+ 0b0000 // opcode=0b011001 ST
+ 0b1001 // opcode=0b011010
+ 0b0001 // opcode=0b011011 JMP
+ 0b1001 // opcode=0b011100
+ 0b0001 // opcode=0b011101 BEQ
+ 0b0001 // opcode=0b011110 BNE
+ 0b0101 // opcode=0b011111 LDR
+ 0b0011 // opcode=0b100000 ADD
+ 0b0011 // opcode=0b100001 SUB
+ 0b0011 // opcode=0b100010 MUL
+ 0b0011 // opcode=0b100011 DIV
+ 0b0011 // opcode=0b100100 CMPEQ
+ 0b0011 // opcode=0b100101 CMPLT
+ 0b0011 // opcode=0b100110 CMPLE
+ 0b1001 // opcode=0b100111
+ 0b0011 // opcode=0b101000 AND
+ 0b0011 // opcode=0b101001 OR
+ 0b0011 // opcode=0b101010 XOR
+ 0b1001 // opcode=0b101011
+ 0b0011 // opcode=0b101100 SHL
+ 0b0011 // opcode=0b101101 SHR
+ 0b0011 // opcode=0b101110 SRA
+ 0b1001 // opcode=0b101111
+ 0b0011 // opcode=0b110000 ADDC
+ 0b0011 // opcode=0b110001 SUBC
+ 0b0011 // opcode=0b110010 MULC
+ 0b0011 // opcode=0b110011 DIVC
+ 0b0011 // opcode=0b110100 CMPEQC
+ 0b0011 // opcode=0b110101 CMPLTC
+ 0b0011 // opcode=0b110110 CMPLEC
+ 0b1001 // opcode=0b110111
+ 0b0011 // opcode=0b111000 ANDC
+ 0b0011 // opcode=0b111001 ORC
+ 0b0011 // opcode=0b111010 XORC
+ 0b1001 // opcode=0b111011
+ 0b0011 // opcode=0b111100 SHLC
+ 0b0011 // opcode=0b111101 SHRC
+ 0b0011 // opcode=0b111110 SRAC
+ 0b1001 // opcode=0b111111
+ )
.ends
// BETA: COMPLETE CIRCUIT
.subckt beta clk reset irq ia[31:0] id[31:0] ma[31:0] moe mrd[31:0] wr mwd[31:0]
Xirq ia[31] irq 0 _irq mux2 // supervisor bit overrides irq
// IF: INSTRUCTION FETCH
Xbeta1 clk reset stall z pcsel[1:0] jt[31:2] ia[31:2] id[31:0] if_pc[31:2] exe_pcr[31:2] if_ir[31:0] beta_1
.connect ia[1:0] 0
// IF-EXE BORDER
Xexepcstall stall#30 if_pc[31:2] exe_pc[31:2] st_pc[31:2] mux2
Xexepc st_pc[31:2] clk#30 exe_pc[31:2] dreg // last pc increment
Xexeirstall stall#32 if_ir[31:0] exe_ir[31:0] st_ir[31:0] mux2
Xexeir st_ir[31:0] clk#32 exe_ir[31:0] dreg
// EXE: INSTRUCTION EXECUTION
Xbeta2 clk reset _irq exe_pc[31:2] exe_pcr[31:2] exe_ir[31:0] exe_alu[31:0] exe_wd[31:0] z pcsel[1:0] jt[31:2] werf wasel wa_rc[4:0] wdata[31:0] mem_ir[31:26] stall beta_2
* reset logic
Xbuff_st stall _stall buffer_4
Xannul_exe reset _stall exe_annul or2
Xexe_annul exe_annul#32 exe_ir[31:0] vdd 0#5 vdd#26 an_exe_ir[31:0] mux2
Xreset_alu _stall#32 exe_alu[31:0] 0#32 exe_st_alu[31:0] mux2
Xreset_wd _stall#32 exe_wd[31:0] 0#32 exe_st_wd[31:0] mux2
// EXE-MEM BORDER
Xmemma exe_st_alu[31:0] clk#32 mem_alu[31:0] dreg
Xmempc exe_pc[31:2] clk#30 mem_pc[31:2] dreg
Xmemir an_exe_ir[31:0] clk#32 mem_ir[31:0] dreg
Xmemwd exe_st_wd[31:0] clk#32 mem_wd[31:0] dreg
* reset logic
Xreset_mem reset#32 mem_ir[31:0] vdd 0#5 vdd#26 rmem_ir[31:0] mux2
Xwd mem_wd[31:0] mwd[31:0] cnxn // output to memory device
Xma mem_alu[31:2] ma[31:2] cnxn // output to memory device
.connect ma[1:0] 0
// MEM: MEMORY WRITE
Xbeta3 reset _irq mem_pc[31:2] rmem_ir[31:0] mem_alu[31:0] moe mrd[31:0] wr werf wasel wa_rc[4:0] wdata[31:0] beta_3
.ends
// BETA STAGE 1: INSTRUCTION FETCH
.subckt beta_1 clk reset _stall z pcsel[1:0] jt[31:2] ia[31:2] id[31:0] pc[31:2] exe_pcr[31:2] ir[31:0]
* stall buffer
Xstbuf _stall stall buffer_8
* PC Control
Xpc clk reset stall z pcsel[1:0] jt[31:2] exe_pcr[30:2] pc[31:2] ia[31:2] pc_annul pc
* annul logic, defaulting IR[31:0] to ADD(R31,R31,R31)=0x87FFFF
Xannulchk pc_annul stall _annul or2
Xannulbuf _annul annul buffer_8
Xannul annul#32 id[31:0] vdd 0#5 vdd#26 ir[31:0] mux2
// niceties for graphing
.connect br_pc[1:0] 0
.connect pc[1:0] 0
.connect pcr[1:0] 0
.connect ia[1:0] 0
.ends
// BETA STAGE 2: INSTRUCTION EXECUTION
.subckt beta_2 clk reset irq pc[31:2] pcr[31:2] ir[31:0] alu[31:0] mwd[31:0] z pcsel[1:0] jt[31:2] werf wasel wa_rc[4:0] wdata[31:0] mem_op[31:26] stall
* control logic
Xexectl irq ir[31:26] pcsel[1:0] asel ra2sel bsel alufn[5:0] exectl
* registers
Xra ir[20:16] ra[4:0] cnxn
Xrb ir[15:11] rb[4:0] cnxn
Xrc ir[25:21] rc[4:0] cnxn
Xregfile clk reset werf wasel ra2sel ra[4:0] rb[4:0] rc[4:0] wa_rc[4:0] wdata[31:0] radata[31:0] rbdata[31:0] mem_op[31:26] stall regfile
// pc branch / relative offset
Xidbuf ir[15:0] _ir[15:0] buffer_8
Xpcr pc[30:2] _ir[15]#13 _ir[15:0] 0 pcr[30:2] _ cs_adder29
.connect pcr[31] pc[31]
.connect pcr[1:0] 0
* calculate Z (reg[A]==0)
Xznor radata[31:0] znor[7:0] nor4
Xznan znor[7:0] znan[1:0] nand4
Xzall znan[1:0] _z nor2
Xzmod _z ir[27] zmod xor2
// branch instruction flag
Xb1 ir[27:26] br1 xor2
Xb2 ir[31] br2 inverter
Xb3 br1 br2 br3 nand2
Xb4 ir[30:28] br4 nand3
Xb5 br3 br4 reset br_flag nor3
// z output
Xzout zmod br_flag z and2
* route JT
Xjt radata[31:2] jt[31:2] cnxn
* ALU input selection
Xasel asel#32 radata[31:0] 0 pcr[30:2] 0#2 a[31:0] mux2
Xbsel bsel#32 rbdata[31:0] ir[15]#16 ir[15:0] b[31:0] mux2
* ALU
Xalu alufn[5:0] a[31:0] b[31:0] alu[31:0] alu
Xmwd rbdata[31:0] mwd[31:0] cnxn
.ends
// BETA STAGE 3: MEMORY WRITE
.subckt beta_3 reset irq pc[31:2] ir[31:0] alu[31:0] moe mrd[31:0] wr werf wasel wa_rc[4:0] wdata[31:0]
// load control signals
Xmemctl reset irq ir[31:26] wasel wdsel[1:0] werf moe wr memctl
// pass out wa_rc
Xwa_rc ir[25:21] wa_rc[4:0] cnxn
// write data selection
Xbwdsel wdsel[1:0] _wdsel[1:0] buffer_8
Xwdsel _wdsel[0]#32 _wdsel[1]#32 pc[31:2] 0#2 alu[31:0] mrd[31:0] 0#32 wdata[31:0] mux4
.ends