Download chisel/src/arithmetic/Arithmetic.scala from Snapkitty/phaser-ags: direct link, hf CLI and curl.
- Browser
- Download file 5.97 kB
-
https://huggingface.co/Snapkitty/phaser-ags/resolve/main/chisel/src/arithmetic/Arithmetic.scala
- Command line
-
hf download hf://Snapkitty/phaser-ags/chisel/src/arithmetic/Arithmetic.scala
-
curl -L -o Arithmetic.scala https://huggingface.co/Snapkitty/phaser-ags/resolve/main/chisel/src/arithmetic/Arithmetic.scala
5.97 kB
| package arithmetic | |
| import chisel3._ | |
| import chisel3.util._ | |
| import nand._ | |
| // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| // ARITHMETIC FROM NAND β Adders and ALU built entirely from | |
| // NAND-derived gates | |
| // | |
| // Hierarchy: NAND2 β XOR/AND/OR β Half Adder β Full Adder β | |
| // Ripple Carry Adder β ALU slice | |
| // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| // βββ HALF ADDER from NAND ββββββββββββββββββββββββββββββββββββββββ | |
| // sum = a β b | |
| // cout = a Β· b | |
| class HalfAdderFromNand extends Module { | |
| val io = IO(new Bundle { | |
| val a = Input(Bool()) | |
| val b = Input(Bool()) | |
| val sum = Output(Bool()) | |
| val cout = Output(Bool()) | |
| }) | |
| val xor = Module(new Xor2FromNand) | |
| xor.io.a := io.a | |
| xor.io.b := io.b | |
| io.sum := xor.io.y | |
| val and = Module(new And2FromNand) | |
| and.io.a := io.a | |
| and.io.b := io.b | |
| io.cout := and.io.y | |
| } | |
| // βββ FULL ADDER from NAND ββββββββββββββββββββββββββββββββββββββββ | |
| // sum = a β b β cin | |
| // cout = (aΒ·b) + (cinΒ·(aβb)) | |
| class FullAdderFromNand extends Module { | |
| val io = IO(new Bundle { | |
| val a = Input(Bool()) | |
| val b = Input(Bool()) | |
| val cin = Input(Bool()) | |
| val sum = Output(Bool()) | |
| val cout = Output(Bool()) | |
| }) | |
| // First half adder: a, b | |
| val ha1 = Module(new HalfAdderFromNand) | |
| ha1.io.a := io.a | |
| ha1.io.b := io.b | |
| // Second half adder: (aβb), cin | |
| val ha2 = Module(new HalfAdderFromNand) | |
| ha2.io.a := ha1.io.sum | |
| ha2.io.b := io.cin | |
| io.sum := ha2.io.sum | |
| // cout = (aΒ·b) + (cinΒ·(aβb)) | |
| val or = Module(new Or2FromNand) | |
| or.io.a := ha1.io.cout | |
| or.io.b := ha2.io.cout | |
| io.cout := or.io.y | |
| } | |
| // βββ RIPPLE CARRY ADDER from NAND βββββββββββββββββββββββββββββββ | |
| // n-bit adder: chain of full adders, carry ripples LSB β MSB | |
| class RippleCarryAdder(val n: Int) extends Module { | |
| val io = IO(new Bundle { | |
| val a = Input(UInt(n.W)) | |
| val b = Input(UInt(n.W)) | |
| val cin = Input(Bool()) | |
| val sum = Output(UInt(n.W)) | |
| val cout = Output(Bool()) | |
| }) | |
| val carries = Wire(Vec(n + 1, Bool())) | |
| carries(0) := io.cin | |
| val sums = Wire(Vec(n, Bool())) | |
| for (i <- 0 until n) { | |
| val fa = Module(new FullAdderFromNand) | |
| fa.io.a := io.a(i) | |
| fa.io.b := io.b(i) | |
| fa.io.cin := carries(i) | |
| sums(i) := fa.io.sum | |
| carries(i+1) := fa.io.cout | |
| } | |
| io.sum := Cat(sums.reverse) | |
| io.cout := carries(n) | |
| } | |
| // βββ ALU SLICE from NAND ββββββββββββββββββββββββββββββββββββββββ | |
| // 1-bit ALU slice with 4 operations selected by 2-bit opcode: | |
| // 00 β AND | |
| // 01 β OR | |
| // 10 β XOR | |
| // 11 β ADD (with carry in/out) | |
| // | |
| // All gates built from NAND2 primitive chain | |
| class AluSliceFromNand extends Module { | |
| val io = IO(new Bundle { | |
| val a = Input(Bool()) | |
| val b = Input(Bool()) | |
| val cin = Input(Bool()) | |
| val op = Input(UInt(2.W)) | |
| val y = Output(Bool()) | |
| val cout = Output(Bool()) | |
| }) | |
| // AND path | |
| val andGate = Module(new And2FromNand) | |
| andGate.io.a := io.a | |
| andGate.io.b := io.b | |
| // OR path | |
| val orGate = Module(new Or2FromNand) | |
| orGate.io.a := io.a | |
| orGate.io.b := io.b | |
| // XOR path | |
| val xorGate = Module(new Xor2FromNand) | |
| xorGate.io.a := io.a | |
| xorGate.io.b := io.b | |
| // ADD path (full adder) | |
| val fa = Module(new FullAdderFromNand) | |
| fa.io.a := io.a | |
| fa.io.b := io.b | |
| fa.io.cin := io.cin | |
| // 4:1 MUX from two levels of 2:1 MUX | |
| // Level 1: mux0 selects AND/OR on op[0], mux1 selects XOR/ADD-sum on op[0] | |
| val mux0 = Module(new Mux2FromNand) | |
| mux0.io.a := andGate.io.y // op[0]=0 β AND | |
| mux0.io.b := orGate.io.y // op[0]=1 β OR | |
| mux0.io.sel := io.op(0) | |
| val mux1 = Module(new Mux2FromNand) | |
| mux1.io.a := xorGate.io.y // op[0]=0 β XOR | |
| mux1.io.b := fa.io.sum // op[0]=1 β ADD | |
| mux1.io.sel := io.op(0) | |
| // Level 2: select between level-1 results on op[1] | |
| val mux2 = Module(new Mux2FromNand) | |
| mux2.io.a := mux0.io.y // op[1]=0 β AND/OR | |
| mux2.io.b := mux1.io.y // op[1]=1 β XOR/ADD | |
| mux2.io.sel := io.op(1) | |
| io.y := mux2.io.y | |
| // Carry out: only meaningful for ADD (op=11), 0 otherwise | |
| // Mux carry: pass cout when op==3, else 0 | |
| val is_add = Module(new And2FromNand) | |
| is_add.io.a := io.op(0) | |
| is_add.io.b := io.op(1) | |
| val carry_mux = Module(new Mux2FromNand) | |
| carry_mux.io.a := false.B | |
| carry_mux.io.b := fa.io.cout | |
| carry_mux.io.sel := is_add.io.y | |
| io.cout := carry_mux.io.y | |
| } | |
| // βββ n-BIT ALU from NAND βββββββββββββββββββββββββββββββββββββββ | |
| // Ripple ALU: chain of AluSliceFromNand for ADD, | |
| // parallel for AND/OR/XOR (carry only used for ADD) | |
| class AluFromNand(val n: Int) extends Module { | |
| val io = IO(new Bundle { | |
| val a = Input(UInt(n.W)) | |
| val b = Input(UInt(n.W)) | |
| val cin = Input(Bool()) | |
| val op = Input(UInt(2.W)) | |
| val y = Output(UInt(n.W)) | |
| val cout = Output(Bool()) | |
| }) | |
| val carries = Wire(Vec(n + 1, Bool())) | |
| carries(0) := io.cin | |
| val results = Wire(Vec(n, Bool())) | |
| for (i <- 0 until n) { | |
| val slice = Module(new AluSliceFromNand) | |
| slice.io.a := io.a(i) | |
| slice.io.b := io.b(i) | |
| slice.io.cin := carries(i) | |
| slice.io.op := io.op | |
| results(i) := slice.io.y | |
| carries(i + 1) := slice.io.cout | |
| } | |
| io.y := Cat(results.reverse) | |
| io.cout := carries(n) | |
| } | |