Skip to main content

Kratos is a fast hardware design language embedded in Python

Project description

Build Status PyPI - Format PyPI - Version Documentation Status

Kratos is a hardware design language written in C++/Python. It differentiates itself from other DSL with the following design philosophy:

  • Fully debuggable: debug hardware just like debugging Python code!

  • Highly efficient: Python frontend powered by Modern C++ binding. Designed with multi-processing in mind.

  • Human-readable verilog: we know how difficult it is to read machine generated verilog. kratos has multiple passes to produce nice-looking verilog.

  • Generator of generators: every python object is a generator that can be modified at any time, even after instantiation. This allows complex passes on the generators without ripping old structure apart.

  • Keep the good parts of verilog: The always block in behavioral verilog is close to other programming languages. Kratos allows you to write python code similar to behavioral verilog

  • Single source of truth: kratos encourages users to infuse generator information inside generator itself. This makes debugging and verification much easier.

  • Static elaboration: kratos allows user to write parametrized code, even in the always block, all in Python.

  • Type checking: kratos check the variable types for each assignment to make sure there is no implicit conversion.

Install

pip install kratos

Pre-built wheels supports all Python 3.5+ on Linux and Python 3.7 on OSX. To build it from scratch, you need a C++17 compatible compiler, such as g++-8.

Documentation and Examples

You can check the documentation at Read the Docs

Here are some examples to showcase the ability of kratos.

Asnyc Reset Register

Python code that parametrizes based on the width. Notice that we specify the sensitivity of the always block when defining seq_code_block.

class AsyncReg(Generator):
    def __init__(self, width):
        super().__init__("register")

        # define inputs and outputs
        self._in = self.input("in", width)
        self._out = self.output("out", width)
        self._clk = self.clock("clk")
        self._rst = self.reset("rst")
        self._val = self.var("val", width)

        # add combination and sequential blocks
        self.add_code(self.seq_code_block)

        self.add_code(self.comb_code_block)

    @always((posedge, "clk"), (posedge, "rst"))
    def seq_code_block(self):
        if self._rst:
            self._val = 0
        else:
            self._val = self._in

    def comb_code_block(self):
        self._out = self._val

Here is the generated verilog

module register (
  input  clk,
  input [15:0] in,
  output reg [15:0] out,
  input  rst
);

logic  [15:0] val;

always @(posedge clk, posedge rst) begin
  if rst begin
    val <= 16'h0;
  end
  else begin
    val <= in;
  end
end
always_comb begin
  out = val;
end
endmodule   // register

Fanout module

This is an example to showcase the kratos’ static elaboration ability in always block. In practice we would not write it this way.

class PassThrough(Generator):
    def __init__(self, num_loop):
        super().__init__("PassThrough", True)
        self.in_ = self.input("in", 1)
        self.out_ = self.output("out", num_loop)
        self.num_loop = num_loop

        self.add_code(self.code)

    def code(self):
        if self.in_ == self.const(1, 1):
            for i in range(self.num_loop):
                self.out_[i] = 1
        else:
            for i in range(self.num_loop):
                self.out_[i] = 0

Here is generated verilog

module PassThrough (
  input  in,
  output reg [3:0] out
);

always_comb begin
  if (in == 1'h1) begin
    out[0:0] = 1'h1;
    out[1:1] = 1'h1;
    out[2:2] = 1'h1;
    out[3:3] = 1'h1;
  end
  else begin
    out[0:0] = 1'h0;
    out[1:1] = 1'h0;
    out[2:2] = 1'h0;
    out[3:3] = 1'h0;
  end
end
endmodule   // PassThrough

How to debug

Because Python is quite slow, By default the debug option is off. You can turn on debugging for individual modules. Here is an example on how to turn on debug (see tests/test_generator.py for more details).

class PassThroughMod(Generator):
    def __init__(self):
        super().__init__("mod1", True)
        self.in_ = self.input("in", 1)
        self.out_ = self.output("out", 1)
        self.wire(self.out_, self.in_)

# ... some other code
class Top(Generator):
    def __init__(self):
        super().__init__("top", True)

        self.input("in", 1)
        self.output("out", 1)

        pass_through = PassThroughMod()
        self.add_child("pass", pass_through)
        self.wire(self["pass"].ports["in"], self.ports["in"])

        self.wire(self.ports.out, self["pass"].ports.out)

mod = Top()
mod_src, debug_info = verilog(mod, debug=True)

You can see the generated verilog:

module top (
  input logic  in,
  output logic  out
);

assign out = in;
endmodule   // top

The pass sub-module disappeared due to the compiler optimization. However, if we print out the debug information, we can see the full trace of debug info on assign out = in;

{
  1: [('/home/keyi/workspace/kratos/tests/test_generator.py', 532)],
  2: [('/home/keyi/workspace/kratos/tests/test_generator.py', 534)],
  3: [('/home/keyi/workspace/kratos/tests/test_generator.py', 535)],
  6: [('/home/keyi/workspace/kratos/tests/test_generator.py', 539),
      ('/home/keyi/workspace/kratos/src/expr.cc', 455),
      ('/home/keyi/workspace/kratos/tests/test_generator.py', 541),
      ('/home/keyi/workspace/kratos/src/expr.cc', 485),
      ('/home/keyi/workspace/kratos/src/pass.cc', 653)]
}

These pass.cc is the pass that removed the pass through module.

If we modified the source code a little bit that change the wire assignment into a combination block, such as

class Top(Generator):
    def __init__(self):
        super().__init__("top", True)

        self.input("in", 1)
        self.output("out", 1)

        pass_through = PassThroughMod()
        self.add_child("pass", pass_through)
        self.wire(self["pass"].ports["in"], self.ports["in"])

        self.add_code(self.code_block)

    def code_block(self):
        self.ports.out = self["pass"].ports.out

We can see the generated verilog will be a little bit verbose:

module top (
  input logic  in,
  output logic  out
);

logic   top$in_0;
assign top$in_0 = in;
always_comb begin
  out = top$in_0;
end
endmodule   // top

And the debug info shows all the information as well:

{
  1: [('/home/keyi/workspace/kratos/tests/test_generator.py', 554)],
  2: [('/home/keyi/workspace/kratos/tests/test_generator.py', 556)],
  3: [('/home/keyi/workspace/kratos/tests/test_generator.py', 557)],
  7: [('/home/keyi/workspace/kratos/tests/test_generator.py', 561), ('/home/keyi/workspace/kratos/src/expr.cc', 455)],
  8: [('/home/keyi/workspace/kratos/tests/test_generator.py', 563)],
  9: [('/home/keyi/workspace/kratos/tests/test_generator.py', 566), ('/home/keyi/workspace/kratos/src/expr.cc', 485)]}

Ecosystem

Kratos has its own ecosystem to program behavioral verilog in Python. Most of them are plugins that will help users to debug, prototype, and testing.

kratos is a programming model for building hardware. The main abstraction in kratos in a Generator. Generator can be modified at any time through passes.

kratos-debug is a GUI for user to view generated verilog. It offers a source viewer to see the line mapping that kratos provides.

kratos-dpi is a DPI plugin that allows users to run arbitrary Python code to emulate a SystemVerilog function. This is extremely helpful for rapid prototyping and testing.

kratos-runtime is a necessary component if you want to debug kratos with standard simulators. It supports value inspection and breakpoints.

kratos-vscode is a Visual Studio Code extension that allows user to debug with Kratos. The simulator has to be loaded with kratos-runtime.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kratos-0.0.16.tar.gz (1.9 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

kratos-0.0.16-cp37-cp37m-manylinux1_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.7m

kratos-0.0.16-cp37-cp37m-macosx_10_14_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.7mmacOS 10.14+ x86-64

kratos-0.0.16-cp36-cp36m-manylinux1_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.6m

kratos-0.0.16-cp35-cp35m-manylinux1_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.5m

File details

Details for the file kratos-0.0.16.tar.gz.

File metadata

  • Download URL: kratos-0.0.16.tar.gz
  • Upload date:
  • Size: 1.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for kratos-0.0.16.tar.gz
Algorithm Hash digest
SHA256 0f3e9a43f4af0bd953e1a4c80af9f3eaa4a6b4eb816522c31263781d0bee5ac4
MD5 1d86d66f177136e4622e26e3eab8ca6f
BLAKE2b-256 3b3e8b1dcf586abc7fc5a644b1cf78486bf0cc89ee47b9bea3d6697bb8bbb28d

See more details on using hashes here.

File details

Details for the file kratos-0.0.16-cp37-cp37m-manylinux1_x86_64.whl.

File metadata

  • Download URL: kratos-0.0.16-cp37-cp37m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for kratos-0.0.16-cp37-cp37m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 bc101d6b27c23c55275542ac7585a26c71ad5bea4fe85dd519fa1aa0e9dccac1
MD5 3aad1781fe6ba8e6402d8f937ef77cbc
BLAKE2b-256 051ff9b4e50cdbdc39f5646cd4cbb269d4d7e0497f2d8e5a61b3f2a97aa0fd7b

See more details on using hashes here.

File details

Details for the file kratos-0.0.16-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: kratos-0.0.16-cp37-cp37m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.7m, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/39.0.1 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.0

File hashes

Hashes for kratos-0.0.16-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 616dfbcf172ab2ee6a686b2c418bb90fc65231cc221f892d687a0fd23f1da822
MD5 590a4bd888312d8355b161777b7a0f46
BLAKE2b-256 494f0b07acaa66b7f3fd602bc5d96fe814442fd40f552e9cd88aea08ee6319ba

See more details on using hashes here.

File details

Details for the file kratos-0.0.16-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

  • Download URL: kratos-0.0.16-cp36-cp36m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.6m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for kratos-0.0.16-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 8eb99aa144f2e617d36ec7f7af1d1e2b80d5b0c731a2c5f01d6c994f64daafb5
MD5 12e1921dd9e7250964f25a68ca05416f
BLAKE2b-256 372b0a0be1ee9c1a320795c29a0ba713b11f51a413a24542d3e7e86f8c6c41aa

See more details on using hashes here.

File details

Details for the file kratos-0.0.16-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

  • Download URL: kratos-0.0.16-cp35-cp35m-manylinux1_x86_64.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: CPython 3.5m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for kratos-0.0.16-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 5c6f34f35c7c959a05299d569e5ecc637f1d2da695a1e72b53e50d754e432dde
MD5 9b28cb064ee4a530f9bc41fd92cf6903
BLAKE2b-256 27f3df42d31a240e2e82dbd06dbef765228c9f2307fe9a3e4a97a59f0f87ba2b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page