Skip to content

Instantly share code, notes, and snippets.

@Hikari9
Created November 30, 2015 14:05
Show Gist options
  • Select an option

  • Save Hikari9/6abfeb3b163832f93bdf to your computer and use it in GitHub Desktop.

Select an option

Save Hikari9/6abfeb3b163832f93bdf to your computer and use it in GitHub Desktop.
CS 152 final lab: f(opcode, z) = (pcsel, ra2sel, bsel, wdsel, alufn, wr, werf)
.include "8clocks.jsim"
.include "nominal.jsim"
.include "stdcell.jsim"
// for alufn connect
.subckt knex a b
.connect a b
.ends
// Subcircuit for final lab
.subckt FINALLAB opcode[5:0] z pcsel[1:0] ra2sel bsel wdsel[1:0] alufn[5:0] wr werf
// alias opcode
.connect A opcode[5]
.connect B opcode[4]
.connect C opcode[3]
.connect D opcode[2]
.connect E opcode[1]
.connect F opcode[0]
// connect inverse opcodes
XinvA A nA inverter
XinvB B nB inverter
XinvC C nC inverter
XinvD D nD inverter
XinvE E nE inverter
XinvF F nF inverter
// 1)
// PCSEL[1:0]
//
// 00 - go to next line
// <everything else>
// 1xx xxx
// LD 011 000
// ST 011 001
// BEQ 011 101 Z=0
// BNE 011 110 Z=1
//
// 01 - branch
// BEQ 011 101 Z=1
// BNE 011 110 Z=0
//
// 10 - jump
// JMP 011 011
//
// possible config:
//
// NO INVERTER IMPLEMENTATION
// pcsel[1] = !A * E * F
// = !(A + !E + !F)
// = !(A + !(E + F))
// = nor2(A, nand2(E, F))
// pcsel[0] = !A * D * (z ^ E)
// = !A * (D * (z ^ E))
// = !(A + !(D * (z ^ E))
// = nand2(A, nand2(D, xor2(z, E)))
//////////// Xpcsel1 E F EF nand2
//////////// Xpcsel2 A EF pcsel[1]
//////////// Xpcsel3 z E zE xor2
//////////// Xpcsel4 D zE DzE nand2
//////////// Xpcsel5 A DzE pcsel[0] nand2
// WITH INVERTER
// pcsel[1] = !A * E * F
// = !(A + !E + !F)
// = nor3(A, !E, !F)
// pcsel[0] = !A * D * (z ^ E)
// = !(A + !D + !(z ^ E))
// = nor3(A, !D, xnor2(z, E))
Xpcsel1 A nE nF pcsel[1] nor3
Xpcsel2 Z E zE xnor2
Xpcsel3 A nD zE pcsel[0] nor3
// 2)
// RA2SEL
// <dont care> - no second register
// 0 - need to read <Rb> (no constant, aka 10xxxx)
// 1 - need to read <Rc> (ST only, aka 011001)
//
// possible config:
// ra2sel = !A * B
// or we can just copy from wr because (wr == ST)
.connect wr ra2sel
// 3)
// BSEL
// <dont care> - ALU not being used
// 0 - 2nd ALU operand is from 2nd register
// (aka 10xxxx)
// 1 - 2nd ALU operand is constant (sign ext c[15:0])
// includes those that add literals (aka 01xxx)
// includes the normal ALU ops (aka 11xxxx)
//
// possible config:
// bsel = B
.connect bsel B
// 4)
// WDSEL[1:0]
// <dont care> - when !WERF
// 00 - <Rc> gets (<PC> + 4)
// JMP (011 011)
// BEQ (011 101)
// BNE (011 110)
//
// 01 - <Rc> gets ALU output
// aka 1xxxxx
//
// 10 - <Rc> gets data memory output (Mem[ALUout])
// LD (011 000)
// LDR (011 111)**** (not necessary)
//
// possible config (we can ignore LDR):
// wdsel[0] = A
// wdsel[1] = !A * !E * !F
// = !(A + E + F)
// = nor3(A, E, F)
.connect wdsel[0] A
Xwdsel A E F wdsel[1] nor3
// possible config (with LDR):
// wdsel[0] = opcode[5]
// wdsel[1] = !A * (D == E) * (E == F)
// = !A * !(D ^ E) * !(E ^ F)
// = !(A + (D ^ E) + (E ^ F))
// = nor3(A, xor(D, E), xor(E, F))
///////// .connect wdsel[0] A
///////// Xwdsel1 D E DxE xor2
///////// Xwdsel2 E F ExF xor2
///////// Xwdsel3 A DxE ExF wdsel[1] nor3
// 5)
// ALUFN
/////////////////////////////////////////////////////////////
// TRUTH TABLE (betaop)
//
// | 000 001 010 011 100 101 110 111
// ----+-----------------------------------------------------
// 000 | ??? ??? ??? ??? ??? ??? ??? ???
// 001 | ??? ??? ??? ??? ??? ??? ??? ???
// 010 | ??? ??? ??? ??? ??? ??? ??? ???
// 011 | LD ST ??? JMP ??? BEQ BNE LDR*
// 100 | ADD SUB MUL* DIV* CMPEQ CMPLT CMPLE ???
// 101 | AND OR XOR ??? SHL SHR SRA ???
// 110 | ADDC SUBC MULC* DIVC* CMPEQC CMPLTC CMPLEC ???
// 111 | ANDC ORC XORC ??? SHLC SHRC SRAC ???
//
// *not included
/////////////////////////////////////////////////////////////
// TRUTH TABLE (ALUFN lab 9 words)
//
// | 000 001 010 011 100 101 110 111
// ----+-----------------------------------------------------
// 000 | ??? ??? ??? ??? ??? ??? ??? ???
// 001 | ??? ??? ??? ??? ??? ??? ??? ???
// 010 | ??? ??? ??? ??? ??? ??? ??? ???
// 011 | ADD** ADD** ??? *** ??? *** *** ***
// 100 | ADD SUB MUL* DIV* CMPEQ CMPLT CMPLE ???
// 101 | AND OR XOR ??? SHL SHR SRA ???
// 110 | ADD SUB MUL* DIV* CMPEQ CMPLT CMPLE ???
// 111 | AND OR XOR ??? SHL SHR SRA ???
//
// ** ST and LD uses ADD
// *** JMP, BEQ, BNE, LDR are dont care
/////////////////////////////////////////////////////////////
// TRUTH TABLE (hex codes from lab 9)
//
// | 000 001 010 011 100 101 110 111
// ----+-----------------------------------------------------
// 000 | ??? ??? ??? ??? ??? ??? ??? ???
// 001 | ??? ??? ??? ??? ??? ??? ??? ???
// 010 | ??? ??? ??? ??? ??? ??? ??? ???
// 011 | 0x00 0x00 ??? *** ??? *** *** ***
// 100 | 0x00 0x01 *** *** 0x33 0x35 0x37 ???
// 101 | 0x18 0x1E 0x16 ??? 0x20 0x21 0x23 ???
// 110 | 0x00 0x01 *** *** 0x33 0x35 0x37 ???
// 111 | 0x18 0x1E 0x16 ??? 0x20 0x21 0x23 ???
// *** don't cares
//
/////////////////////////////////////////////////////////////
// TRUTH TABLE (bin codes from lab 9)
//
// | 000 001 010 011 100 101 110 111
// ----+-----------------------------------------------------
// 000 | ??? ??? ??? ??? ??? ??? ??? ???
// 001 | ??? ??? ??? ??? ??? ??? ??? ???
// 010 | ??? ??? ??? ??? ??? ??? ??? ???
// 011 | 000000 000000 ??? *** ??? *** *** ***
// 100 | 000000 000001 *** *** 110011 110101 110111 ???
// 101 | 011000 011110 010110 ??? 100000 100001 100011 ???
// 110 | 000000 000001 *** *** 110011 110101 110111 ???
// 111 | 011000 011110 010110 ??? 100000 100001 100011 ???
/////////////////////////////////////////////////////////////
// with K-map solver help from http://www.32x8.com/circuits6
// A, B, C, D, E, F = op[5:0]
// possible config:
// alufn[5] = D
.connect D alufn[5]
// alufn[4] = A * (C ^ D)
// = !(!A + !(C ^ D)
// = nor2(!A, xnor2(C, D))
Xalufn1 C D CxD xnor2
Xalufn2 nA CxD alufn[4] nor2
// alufn[3] = A * C * !E * !D
// = nor4(!A, !C, E, D)
Xalufn3 nA nC E D alufn[3] nor4
// alufn[2] = A * (E + F) * (C ^ D)
// = !(!((E + F) * A) + !(C ^ D))
// = nor2(oai21(E, F, A), xnor2(C, D))
// note: CxD is reused from Xalufn1
Xalufn4 E F A nodeEFA oai21
Xalufn5 nodeEFA CxD alufn[2] nor2
// alufn[1] = E + !C * D * !F + A * C * !D * F
// = !(!E * !(!C * D * !F) * !(A * C * !D * F))
// = nand3(!E, nand3(!C, D, !F), nand4(A, C, !D, F))
Xalufn6 nC D nF nandCDF nand3
Xalufn7 A C nD F nodeACDF nand4
Xalufn8 nE nandCDF nodeACDF alufn[1] nand3
// alufn[0] = !C * F + !C * D + D * F + D * E
// = F * (!C + D) + D * (!C + E)
// = !(!((!C + D) * F) * !((!C + E) * D))
// = nand2(oai21(!C, D, F), oai21(!C, E, D))
Xalufn9 nC D F nodeCDF oai21
Xalufn10 nC E D nodeCED oai21
Xalufn11 nodeCDF nodeCED alufn[0] nand2
// 6)
// WR
// 0 - not writing to memory (aka not ST)
// 1 - writing to memory (aka ST, 011 001)
//
// possible config:
// wr = !A * B * !D * !E * F
// wr = !(A + !B + D + E + !F)
// wr = !(A + D + E + (!B + !F))
// wr = !(A + D + E + !(B * F))
// wr = nor4(A, D, E, nand2(B, F))
//////////// XWR1 opcode[4] opcode[0] op40 nand2
//////////// XWR2 opcode[5] opcode[2] opcode[1] op40 wr nor4
// note: wr = !werf, we can just use inverter cuz cheaper
Xwr werf wr inverter
// 7)
// WERF
//
// 0 - not writing to regfile
// aka ST (011 001)
// note: there is no 010 001 opcode
// we can ignore C
//
// 1 - writing to regfile
// aka not ST
//
// note: werf = !wr, but we need to set a circuit for one of them
//
// NO INVERTER IMPLEMENTATION
// possible config:
// werf = A + !B + D + E + !F
// = !(!A * B * !D * !E * F)
// = !(B * F * (!A * !D * !E))
// = !(B * F * !(A + D + E))
// = nand3(B, F, nor3(A, D, E))
//////////// Xwerf1 A D E nodeADE nor3
//////////// Xwerf2 B F nodeADE werf nand3
// WITH INVERTERS (lowest load/delay)
// werf = A + !B + D + E + !F
// = !(!A * B * !D * !E * F)
// = !(!(A + D) * B * !E * F)
// = nand4(nor2(A, D), B, !E, F)
Xwerf1 A D AxD nor2
Xwerf2 AxD B nE F werf nand4
.ends
.include "FINALLAB.jsim"
Xconn clk[7:1] opcode[5:0] z knex
Xlab opcode[5:0] z pcsel[1:0] ra2sel bsel wdsel[1:0] alufn[5:0] wr werf FINALLAB
// Xmem vdd 0 0
// + opcode[5:0] z
// + pcsel[1:0] ra2sel bsel wdsel[1:0] alufn[5:0] wr werf //This is the corresponding below
// + $memory width=14 nlocations=128
// //How to define stuff inside
// // In include file
// + contents=( //Similar to the RC RA RB thing for BSIM, so first thing we put is opCode
// + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 //2 zeroes for each opCode First 2 is opCode0 next 2 is opCode1 ... until opCode7
// + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
// + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 //We have now filled up our memory with necessary instructions
// + 0b000110000000001 //Spaces should exist, this is load LD, z=0
// + 0b000110000000001 //LD, z=1
// + 0b001100000000010 //This is ST, first 6 digits is the SEL stuff at slide 9 for the ALU 7th 6 0's is ADD
// + 0b001100000000010 //ST
// + 0 0
// + 0b100000000000001 //JMP Note: Don't Care is 00
// + 0b100000000000001 //JMP Note(for reference lang): Last 2 bits is Wr and WERF
// + 0 0
// + 0b000000000000001 //BEQ with z = 0
// + 0b010000000000001 //BEQ with z = 1 //note: making it 10 turns it into JUMP
// + 0b010000000000001 //BNE with z = 0
// + 0b000000000000001 //BNE with z = 1
// + )
.plotdef alufnop
+ ADD SUB ??? ??? ??? ??? ??? ??? // 000
+ ??? ??? ??? ??? ??? ??? ??? ??? // 001
+ ??? ??? ??? ??? ??? ??? XOR ??? // 010
+ AND ??? ??? ??? ??? ??? OR ??? // 011
+ SHL SHR ??? SRA ??? ??? ??? ??? // 100
+ ??? ??? ??? ??? ??? ??? ??? ??? // 101
+ ??? ??? ??? CMPEQ ??? CMPLT ??? CMPLE // 110
+ ??? ??? ??? ??? ??? ??? ??? ??? // 111
//000 001 010 011 100 101 110 111
.tran 640ns
.plot betaop(clk[7:2]) // LOOK AT NOMINAL LOL It shows the operation's name due to this thingy
.plot d(z)
.plot pcsel[1:0]
.plot d(ra2sel)
.plot d(bsel)
.plot wdsel[1:0]
.plot alufnop(alufn[5:0])
.plot d(wr)
.plot d(werf)
@Hikari9
Copy link
Author

Hikari9 commented Nov 30, 2015

OPCODE to ALUFN credits to K-map solver from http://www.32x8.com/circuits6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment