Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MyHDL: Designing Digital Hardware with Python (PyConTW 2013)

MyHDL: Designing Digital Hardware with Python (PyConTW 2013)

Jan Decaluwe

May 26, 2013
Tweet

Other Decks in Programming

Transcript

  1. One more thing ... The digital design of these two

    chips was completely done with Python! (using the MyHDL library)
  2. Mainstream digital design • language based • such a language

    is called a Hardware Description Language (HDL) • industry standard HDLs: Verilog, VHDL Question: what makes an HDL special?
  3. What is the difference between an HDL and a programming

    language? Answer: 4317 lines of Python code :-) (That is the line count of the MyHDL library.)
  4. Digital hardware system characteristics • massive amount of concurrent "threads"

    • communication through "signals" • actions triggered by "events" on signals • deterministic "by construction" • fine-grained control of data type bit widths Requirement: an HDL must natively support these characteristics
  5. What is an HDL? • An HDL is an event-driven

    microthread programming language, with built-in determinism. • An HDL must also implement a hardware- friendly type system. • Warning: Many hardware designers don't want to hear that it's all just software programming!
  6. The design of MyHDL Our goal is to design a

    Python library that supports the following features • Microthreads • Events that trigger actions • Deterministic communication • Hardware friendly type system
  7. Determinism in an HDL • separate phases for: value updates

    computations • computation order does not matter! • More info: www.sigasi.com/content/vhdls-crown-jewel
  8. The leaf object of determinism • the Signal class •

    Signals implement value buffering: s = Signal(0) s.next = 5 • value updates occur automatically by a scheduler (a.k.a. the "simulator") • if all communication goes through Signals, the model is deterministic
  9. Events • Events trigger computation actions • Signals also define

    events: ▪ value changes ▪ 0->1 transition (a "posedge") ▪ 1->0 transition (a "negedge") • Commonly used global synchronizing event: the "clock edge" • Other events exist, e.g. waiting for a delay
  10. Microthreads • we need massive concurrency • the threads should

    be super lightweight • as lightweight as a function ...
  11. Microthread implementation • Python generator functions to the rescue #

    z, a, b, sel are Signal objects (outer scope) def mux(): while True: # loop forever yield a, b, sel # wait on a value change if sel: # of a, b, or sel z.next = a else: z.next = b
  12. Using decorators to create generators: @instance • @instance decorator creates

    a generator from a generator function @instance # equivalent to mux = mux() def mux(): while True: yield a, b, sel if sel: z.next = a else: z.next = b
  13. The @always decorator • @always decorator abstracts an outer "while

    True" loop followed by a "yield" statement @always(a, b, sel) def mux(): if sel: z.next = a else: z.next = b
  14. Combinatorial logic: @always_comb • @always_comb decorator automatically infers the "sensitivity"

    to input value changes @always_comb def mux(): if sel: z.next = a else: z.next = b
  15. Sequential logic: @always_seq • @always_seq infers the reset functionality reset

    = ResetSignal(0, active=0, async=True) @always_seq(clock.posedge, reset=reset) def dff(): q.next = d • Equivalent code: @always(clock.posedge, reset.negedge) def dff(): if reset == 0: q.next = 0 # initial value of q else: q.next = d
  16. Decorators are a great tool to create a domain-specific language

    • @instance: most general, multiple yield statements. • @always: single yield statement, abstracts "while True" loop. • @always_comb: automatically infers combinatorial sensitivity. • @always_seq: automatically infers the reset functionality for sequential logic. A unique feature of MyHDL!
  17. MyHDL is minimalistic • only features that are strictly necessary

    are implemented • use native Python features as much as possible, e.g.: ◦ lists for random access memory (RAM) ◦ tuples for read-only memory (ROM) • a hardware module is modeled by a function that returns generators • hierarchy is modeled by a submodule "call"
  18. Modeling hierarchy def module(out1,..., in2,..., clock, reset): sig1 = Signal(...)

    ... inst1 = submodule(...) ... @always_seq(clock.posedge, reset=reset) def gen1(): ... @always_comb(): def gen2(): ... return inst1,..., gen1, gen2,...
  19. Hardware-friendly type system • based on integer arithmetic • fine-grained

    control of bit width for efficiency A Puzzle: • given: a in range(0, 8) and b in range(-8, 8) • calculate c = a + b • For example: 7 + -2 = ?
  20. 7 + -2: The Verilog answer reg [2:0] a; reg

    signed [3:0] b; reg signed [4:0] c; ... c <= a + b; Answer: 7 + -2 = -11
  21. 7 + -2: The VHDL answer signal a: unsigned(2 downto

    0); signal b: signed(3 downto 0); signal c: signed(4 downto 0); ... c <= a + b; Answer: test.vhd:24:10: no function declarations for operator "+": compilation error.
  22. What's wrong with integer arithmetic in Verilog/VHDL • based on

    low-level, non-abstract types: signed/unsigned • mixed expressions are problematic • Verilog casts everything to unsigned! • VHDL's strong typing doesn't work well with low-level types
  23. Integer arithmetic in MyHDL • the Python way: based on

    good old integers • the intbv class: "integer with bit vector capabilities" • specify range for implementation efficiency a = intbv(0, min=0, max=8) b = intbv(0, min=-8, max=8) • range boundaries reused in value assertions • slicing & indexing interface to access the bits z.next = a[2:0]
  24. Sidenote: Synthesis • a "synthesis tool" is a compiler •

    it compiles an HDL hardware model into a gate-level implementation • the entry point of a fully automated back-end • only a restricted HDL subset is synthesizable: the Register Transfer Level (RTL) • available from multiple vendors in all price categories (free to $$$) • Verilog and VHDL only!
  25. Conversion: connecting to standard design flows • a subset of

    MyHDL can be automatically converted to Verilog/VHDL • the convertor maintains the abstraction level • however, it supports some unique MyHDL features and automates some tedious tasks • creates readable VHDL/Verilog that integrates seamlessly in the design flow • the convertible subset is much broader than the synthesizable subset
  26. Conversion example • MyHDL code: a = Signal(intbv(0, min=0, max=8))

    b = Signal(intbv(0, min=-8, max=8)) c = Signal(intbv(0, min=-8, max=15)) c.next = a + b • Conversion to Verilog: c <= $signed({1'b0, a}) + b; • Conversion to VHDL: c <= signed(resize(a, 5)) + b; • The convertor does the casts and resizings, so you don't have to!
  27. MyHDL's strongest point: Verification • Verification is by far the

    hardest task in hardware design • With MyHDL, hardware verification engineers benefit from Python's expressive power and ecosystem • Test-driven design (TTD) for hardware (with unittest, py.test...) • The foundation is an event-driven simulator provided by MyHDL
  28. The MyHDL simulator • input is a (hierarchical) list of

    generators, that communicate through signals update signal values check which generators become active run active generators in any order
  29. pypy and MyHDL: a dream team • pypy is an

    alternative, Python 2.7 compliant Python interpreter • JIT technology for speed-up • benchmark simulations run 8 - 20 faster • within speed range of commercial VHDL/Verilog simulators • overnight game changer for "free" :-)
  30. Future • fixed point support in conversion • attribute name

    lookup support in convertor (interfaces) • Python 3.0 (gradual process)
  31. MyHDL resources • myhdl.org has all the info on: ◦

    Manual & examples ◦ Download & installation instructions ◦ Newsgroup & mailing list ◦ Users, projects & success stories ◦ Development • @MyHDL on twitter • Development with mercurial on Bitbucket