diff --git a/lambdalib/analoglib/__init__.py b/lambdalib/analoglib/__init__.py index ed40b80..29a5aec 100644 --- a/lambdalib/analoglib/__init__.py +++ b/lambdalib/analoglib/__init__.py @@ -1,3 +1,6 @@ from .la_pll.la_pll import PLL +from .la_ring.la_ring import Ring -__all__ = ['PLL'] +__all__ = ['PLL', + 'Ring' + ] diff --git a/lambdalib/analoglib/la_ring/la_ring.py b/lambdalib/analoglib/la_ring/la_ring.py new file mode 100644 index 0000000..a26b9dd --- /dev/null +++ b/lambdalib/analoglib/la_ring/la_ring.py @@ -0,0 +1,30 @@ +from lambdalib.lambdalib import Lambda +from lambdalib.stdlib import Inv +from lambdalib.stdlib import Buf +from lambdalib.stdlib import Nand2 +from lambdalib.stdlib import Nand3 +from lambdalib.stdlib import Nand4 +from lambdalib.stdlib import Nor2 +from lambdalib.stdlib import Nor3 +from lambdalib.stdlib import Nor4 + + +class Ring(Lambda): + def __init__(self): + name = 'la_ring' + super().__init__(name, __file__) + + # deps + self.add_depfileset(Inv(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Buf(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nand2(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nand3(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nand4(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nor2(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nor3(), depfileset='rtl', fileset='rtl') + self.add_depfileset(Nor4(), depfileset='rtl', fileset='rtl') + + +if __name__ == "__main__": + d = Ring() + d.write_fileset(f"{d.name}.f", fileset="rtl") diff --git a/lambdalib/analoglib/la_ring/rtl/la_ring.v b/lambdalib/analoglib/la_ring/rtl/la_ring.v new file mode 100644 index 0000000..418fd74 --- /dev/null +++ b/lambdalib/analoglib/la_ring/rtl/la_ring.v @@ -0,0 +1,62 @@ +/************************************************************************** + * Function: Generic Ring Oscillator + * Copyright: Lambda Project Authors. All rights Reserved. + * License: MIT (see LICENSE file in Lambda repository) + *************************************************************************/ +module la_ring #(parameter PROP = "", // cell property (vt, strength, ..) + parameter STAGES = 7, // number of stages (must be odd #) + parameter GATE = "inv" // inverting gate (inv,nand2,nand3,..nor4) + ) + ( + input en, + output out + ); + + wire [STAGES-1:0] stage; + + genvar i; + generate + for (i = 0; i < STAGES; i = i + 1) begin : gen_stages + if (i == 0) + la_nand2 #(.PROP(PROP)) i0 (.a(stage[STAGES-1]), .b(en), + .z(stage[i])); + else if (GATE == "inv") + la_inv #(.PROP(PROP)) i0 (.a(stage[i-1]), + .z(stage[i])); + else if (GATE == "nand2") + la_nand2 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), + .z(stage[i])); + else if (GATE == "nand3") + la_nand3 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), .c(stage[i-1]), + .z(stage[i])); + else if (GATE == "nand4") + la_nand4 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), .c(stage[i-1]), .d(stage[i-1]), + .z(stage[i])); + else if (GATE == "nor2") + la_nor2 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), + .z(stage[i])); + else if (GATE == "nor3") + la_nor3 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), .c(stage[i-1]), + .z(stage[i])); + else if (GATE == "nor4") + la_nor4 #(.PROP(PROP)) i0 (.a(stage[i-1]), .b(stage[i-1]), .c(stage[i-1]), .d(stage[i-1]), + .z(stage[i])); + else + begin + initial + $display("ERROR: Unimplemented gate type: %s", GATE); + end + end + endgenerate + + la_buf #(.PROP(PROP)) ibuf (.a(stage[STAGES-1]), .z(out)); + + // ERROR CHECKING + initial + begin + if (STAGES % 2 == 0) begin + $display("ERROR: Ring oscillator stages set to %0d. Must be odd for oscillation.", STAGES); + $finish; + end + end +endmodule