Assignment 01
Logic Gates in MyHDL
Assignment
Starting with only Nand
, 0
, and 1
, create MyHDL code for the following 16 functions (see also Figure 1.2 in Ch1). Submissions are due 1 week after A01 appears in the autograder.
x | 0 0 1 1 | ||
---|---|---|---|
Function | y | 0 1 0 1 | submission filename |
constant 0 | 0 | 0 0 0 0 | Constant0.py |
And | x and y | 0 0 0 1 | And.py |
x And Not y | x and (not y) | 0 0 1 0 | Xandnoty.py |
x | x | 0 0 1 1 | X.py |
Not x And y | (not x) and y | 0 1 0 0 | Notxandy.py |
y | y | 0 1 0 1 | Y.py |
Xor | (x and (not y)) or (not (x and y)) | 0 1 1 0 | Xor.py |
Or | x or y | 0 1 1 1 | (none) |
Nor | not (x or y) | 1 0 0 0 | Nor.py |
Equivalence | x is y | 1 0 0 1 | Equivalence.py |
Not y | not y | 1 0 1 0 | Not.py |
If y then x | x or (not y) | 1 0 1 1 | Ifythenx.py |
Not x | not x | 1 1 0 0 | Not.py |
If x then y | (not x) or y | 1 1 0 1 | Ifxtheny.py |
Nand | not (x and y) | 1 1 1 0 | (none) |
constant 1 | 1 | 1 1 1 1 | Constant1.py |
- Note
- Do not submit files for
Or.py
orNand.py
. These are available in the Autograder environment for your modules to import. Your files can usefrom Nand import Nand
to use the provided implementation. - Hint1
- Once you have a working implementation for
And
, you can use it in subsequent designs. - Hint2
- When you are working on this assignment (either on your personal machine or silo), keep all these files in the same directory for simpler importing.
MyHDL boilerplate
For each primitive gate, you can start with the following "boilerplate" code and add your implementation:
from myhdl import block, always_comb, Signal # bare minimum, possibly sufficient from Nand import Nand # import any gates you've already built, if you need them from test import test # import the test harness # implement the gate # replace "Name_of_gate_to_implement" with Nor, Xor, and the rest. @block def Name_of_gate_to_implement(a, b, z): # your code here # create instances of Nand or other blocks # connect them using Signal @always_comb def f(): # your code here # z.next = one_of_your_signals_here return f # run the test function, using the name of the gate you implemented above if __name__ == "__main__": test = test_gate(Name_of_gate_to_implement) test.run_sim()
Provided gate: Nand
Below is the implementation of Nand
. Remember that this one is allowed to use Python's and
and not
keywords.
# filename: Nand.py from myhdl import block, always_comb @block def Nand(a, b, out): @always_comb def f(): out.next = not (a and b) return f
Provided gate: Not
Below is an implementation of Not
, using Nand
as its building block.
# filename: Not.py from myhdl import block, always_comb, Signal from Nand import Nand @block def Not(a, z): out = Signal(0) n1 = Nand(a, 1, out) @always_comb def f(): z.next = out return f, n1
Provided gate: Or
As a final example, the Or
gate can be implmented using any of the gates already described (Nand
and Not
).
# filename: Or.py from myhdl import block, always_comb, Signal, intbv from Nand import Nand from Not import Not @block def Or(a, b, z): nota = Signal(0) notb = Signal(0) out = Signal(0) n1 = Not(a, nota) n2 = Not(b, notb) n3 = Nand(nota, notb, out) @always_comb def f(): z.next = out return f, n1, n2, n3
Test harness
You can use the following test harness for all of the 2-input gates.
from myhdl import block, instance, delay, Signal # two-input gate test harness @block def test_two(func): a, b, z = [Signal(0) for _ in range(3)] fun1 = func(a, b, z) @instance def tester(): print("a b z") for i in [0, 1]: for j in [0, 1]: a.next, b.next = i, j yield delay(1) print(a, b, int(z)) return fun1, tester # one-input gate test harness @block def test_one(func): a, z = [Signal(0) for _ in range(2)] fun1 = func(a, z) @instance def tester(): print("a z") for i in [0, 1]: a.next = i yield delay(1) print(a, int(z)) return fun1, tester
Comlete example: Or
A complete example like you would turn in for Or
is shown below:
# save this file as Or.py from myhdl import block, always_comb, Signal from Nand import Nand # provided by Autograder from Not import Not # assume we also uploaded a working Not.py from Test import test_two @block def Or(a, b, z): nota = Signal(0) notb = Signal(0) out = Signal(0) n1 = Not(a, nota) n2 = Not(b, notb) n3 = Nand(nota, notb, out) @always_comb def f(): z.next = out return f, n1, n2, n3 if __name__ == "__main__": test = test_two(Or) test.run_sim()
Supplemental: implementations
You can find implementations of Test.py
, Nand.py
, Or.py
, and Not.py
here:
https://github.com/ENGR110/ENGR110.github.io/tree/master/assignments/supplemental/A01