# Sequential Logic ###### tags: `computerArchitecture` `SequentialLogid` Building some memory chip !!!!!! [Reference Video](https://www.youtube.com/watch?v=lo54MEu7u9A&t=1246s) ## bit component The clock input which is implicit in any of there memory related things. d flip flop has the delay for one cycle behavior if --> we think of a multiplexer ![](https://i.imgur.com/y2fJcLp.png) if we unset that load bit and unset the input or rather set it to zero, the value not going to change because it is loop back around ### HDLL Code ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/a/Bit.hdl /** * 1-bit register: * If load[t] == 1 then out[t+1] = in[t] * else out does not change (out[t+1] = out[t]) */ CHIP Bit { IN in, load; OUT out; PARTS: // Put your code here: Mux(a=DFFout, b=in, sel=load, out=muxOut); DFF(in=muxOut, out=out, out=DFFout ); } ``` ## Register the register look like just the bit, except it's an array of 16 pieces of memory instead of single one. I not to drawn the diagram(laziness is a programmer's great est attribute ### HDL code ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/a/Register.hdl /** * 16-bit register: * If load[t] == 1 then out[t+1] = in[t] * else out does not change */ CHIP Register { IN in[16], load; OUT out[16]; PARTS: // Put your code here: Bit(in=in[0], load=load, out=out[0]); Bit(in=in[1], load=load, out=out[1]); Bit(in=in[2], load=load, out=out[2]); Bit(in=in[3], load=load, out=out[3]); Bit(in=in[4], load=load, out=out[4]); Bit(in=in[5], load=load, out=out[5]); Bit(in=in[6], load=load, out=out[6]); Bit(in=in[7], load=load, out=out[7]); Bit(in=in[8], load=load, out=out[8]); Bit(in=in[9], load=load, out=out[9]); Bit(in=in[10], load=load, out=out[10]); Bit(in=in[11], load=load, out=out[11]); Bit(in=in[12], load=load, out=out[12]); Bit(in=in[13], load=load, out=out[13]); Bit(in=in[14], load=load, out=out[14]); Bit(in=in[15], load=load, out=out[15]); } ``` ## Program Counter if -> multiplexer ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/a/PC.hdl /** * A 16-bit counter with load and reset control bits. * if (reset[t] == 1) out[t+1] = 0 * else if (load[t] == 1) out[t+1] = in[t] * else if (inc[t] == 1) out[t+1] = out[t] + 1 (integer addition) * else out[t+1] = out[t] */ CHIP PC { IN in[16],load,inc,reset; OUT out[16]; PARTS: // Put your code here: Register(in=resetMuxOut, load=true, out=out, out=regOut); Inc16(in=incIn, out=incOut); // if reset = 1 Mux16(a=loadMuxOut, b[0..15]=false, sel=reset, out=resetMuxOut); // if load = 1 Mux16(a=incMuxOut, b=in, sel=load, out=loadMuxOut); // if inc = 1 Mux16(a=regOut, b=incOut, sel=inc, out=incMuxOut); } ``` ## RAM8 8 memory of 8 register each 16-bit Right off the bat, we need the 8 register ``` Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); Register(in=, load=, out=); ``` Out hold the value store at the memory location specified by address Now, we actually have two decision, probably more than that. - One decision is where does this in value go - Another decision is which register the out value come from So rat of the bat. I thinking that there's both mux and de mux happening here ## Out put We could use 8waymux to decide which register should be loaded into the memory and specified the address. ``` //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=, out=); ``` ## In put ``` //input DMux8Way(in=load, sel=address, a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); ``` Source Code ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/a/RAM8.hdl /** * Memory of 8 registers, each 16 bit-wide. Out holds the value * stored at the memory location specified by address. If load==1, then * the in value is loaded into the memory location specified by address * (the loaded value will be emitted to out from the next time step onward). */ CHIP RAM8 { IN in[16], load, address[3]; OUT out[16]; PARTS: // Put your code here: //input DMux8Way(in=load, sel=address, a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); Register(in=in, load=da, out=regA); Register(in=in, load=db, out=regB); Register(in=in, load=dc, out=regC); Register(in=in, load=dd, out=regD); Register(in=in, load=de, out=regE); Register(in=in, load=df, out=regF); Register(in=in, load=dg, out=regG); Register(in=in, load=dh, out=regH); //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=, out=); } ``` ok, this is our kink of memory bank if we could kind of squint at it, you've got the central bank of memory and then on either side of the memory, you have this complex of demux and mux that are routing value in and out of it. ### RAM64, a bank of 64 register It almost exactly the same what we did for ram 8 So what is the same , what's different We could actually know our address is six bit which is different from what we did one The most significant bit is going to decide which of these ram 8 we address and then the least significant bits are going to sub select with that ram 8 ![](https://i.imgur.com/p7WORxX.png) ``` DMux8Way(in=load, sel=address[0..2], a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); // use lest signifcant to be selector ``` ``` Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=address[0..2], out=out); } ``` ``` RAM8(in=in, load=da, address=address[3..5], out=regA); ``` ### Source code ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/a/RAM64.hdl /** * Memory of 64 registers, each 16 bit-wide. Out holds the value * stored at the memory location specified by address. If load==1, then * the in value is loaded into the memory location specified by address * (the loaded value will be emitted to out from the next time step onward). */ CHIP RAM64 { IN in[16], load, address[6]; OUT out[16]; PARTS: // Put your code here: //input DMux8Way(in=load, sel=address[0..2], a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); // use lest signifcant to be selector RAM8(in=in, load=da, address=address[3..5], out=regA); RAM8(in=in, load=db, address=address[3..5],out=regB); RAM8(in=in, load=dc, address=address[3..5], out=regC); RAM8(in=in, load=dd, address=address[3..5], out=regD); RAM8(in=in, load=de, address=address[3..5], out=regE); RAM8(in=in, load=df, address=address[3..5], out=regF); RAM8(in=in, load=dg, address=address[3..5], out=regG); RAM8(in=in, load=dh, address=address[3..5], out=regH); //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=address[0..2], out=out); } ``` ### RAM 4k(4096) That the logic is exactly the same, the only question is how you handling these addresses bits Source code We have to assign 6 bit to RAM64, ``` // This file is part of the materials accompanying the book // "The Elements of Computing Systems" by Nisan and Schocken, // MIT Press. Book site: www.idc.ac.il/tecs // File name: projects/03/b/RAM512.hdl /** * Memory of 512 registers, each 16 bit-wide. Out holds the value * stored at the memory location specified by address. If load==1, then * the in value is loaded into the memory location specified by address * (the loaded value will be emitted to out from the next time step onward). */ CHIP RAM512 { IN in[16], load, address[9]; OUT out[16]; PARTS: // Put your code here: //input DMux8Way(in=load, sel=address[0..2], a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); // use lest signifcant to be selector RAM64(in=in, load=da, address=address[3..8], out=regA); //6bits = 64 RAM64(in=in, load=db, address=address[3..8], out=regB); RAM64(in=in, load=dc, address=address[3..8], out=regC); RAM64(in=in, load=dd, address=address[3..8], out=regD); RAM64(in=in, load=de, address=address[3..8], out=regE); RAM64(in=in, load=df, address=address[3..8], out=regF); RAM64(in=in, load=dg, address=address[3..8], out=regG); RAM64(in=in, load=dh, address=address[3..8], out=regH); //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=address[0..2], out=out); } ``` ### RAM 512 ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/b/RAM4K.hdl /** * Memory of 4K registers, each 16 bit-wide. Out holds the value * stored at the memory location specified by address. If load==1, then * the in value is loaded into the memory location specified by address * (the loaded value will be emitted to out from the next time step onward). */ CHIP RAM4K { IN in[16], load, address[12]; OUT out[16]; PARTS: // Put your code here: // Put your code here: //input DMux8Way(in=load, sel=address[0..2], a=da, b=db, c=dc, d=dd, e=de, f=df, g=dg, h=dh); // use lest signifcant to be selector RAM512(in=in, load=da, address=address[3..11], out=regA); //9bit = 512 RAM512(in=in, load=db, address=address[3..11], out=regB); RAM512(in=in, load=dc, address=address[3..11], out=regC); RAM512(in=in, load=dd, address=address[3..11], out=regD); RAM512(in=in, load=de, address=address[3..11], out=regE); RAM512(in=in, load=df, address=address[3..11], out=regF); RAM512(in=in, load=dg, address=address[3..11], out=regG); RAM512(in=in, load=dh, address=address[3..11], out=regH); //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, f=regF, g=regG, h=regH, sel=address[0..2], out=out); } ``` ## RAM 16K(4096\*4) ``` // This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/03/b/RAM16K.hdl /** * Memory of 16K registers, each 16 bit-wide. Out holds the value * stored at the memory location specified by address. If load==1, then * the in value is loaded into the memory location specified by address * (the loaded value will be emitted to out from the next time step onward). */ CHIP RAM16K { IN in[16], load, address[14]; OUT out[16]; PARTS: // Put your code here: //input DMux8Way(in=load, sel=address[0..1], a=da, b=db, c=dc, d=dd); // use lest signifcant to be selector RAM4K(in=in, load=da, address=address[2..13], out=regA); RAM4k(in=in, load=db, address=address[2..13], out=regB); RAM4k(in=in, load=dc, address=address[2..13], out=regC); RAM4k(in=in, load=dd, address=address[2..13], out=regD); //decide the output part Mux8Way16(a=regA, b=regB, c=regC, d=regD, e=regE, sel=address[0..1], out=out); } ```