GithubHelp home page GithubHelp logo

pyhdi / veriloggen Goto Github PK

View Code? Open in Web Editor NEW
298.0 34.0 57.0 12.56 MB

Veriloggen: A Mixed-Paradigm Hardware Construction Framework

License: Apache License 2.0

Makefile 3.50% Python 90.90% Verilog 0.44% Shell 0.01% Jupyter Notebook 5.01% C++ 0.03% Tcl 0.11% Dockerfile 0.01%
verilog-hdl python pyverilog high-level-synthesis hardware hardware-construction-language compiler

veriloggen's Introduction

Veriloggen

CI Build Status

A Mixed-Paradigm Hardware Construction Framework

Copyright 2015, Shinya Takamaeda-Yamazaki and Contributors

License

Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)

Publication

If you use Veriloggen in your research, please cite my paper about Pyverilog. (Veriloggen is constructed on Pyverilog.)

  • Shinya Takamaeda-Yamazaki: Pyverilog: A Python-based Hardware Design Processing Toolkit for Verilog HDL, 11th International Symposium on Applied Reconfigurable Computing (ARC 2015) (Poster), Lecture Notes in Computer Science, Vol.9040/2015, pp.451-460, April 2015. Paper
@inproceedings{Takamaeda:2015:ARC:Pyverilog,
title={Pyverilog: A Python-Based Hardware Design Processing Toolkit for Verilog HDL},
author={Takamaeda-Yamazaki, Shinya},
booktitle={Applied Reconfigurable Computing},
month={Apr},
year={2015},
pages={451-460},
volume={9040},
series={Lecture Notes in Computer Science},
publisher={Springer International Publishing},
doi={10.1007/978-3-319-16214-0_42},
url={http://dx.doi.org/10.1007/978-3-319-16214-0_42},
}

What's Veriloggen?

Veriloggen is a mixed-paradigm framework for constructing a hardware in Python.

Veriloggen provides a low-level abstraction of Verilog HDL AST. You can build up a hardware design written in Verilog HDL very easily by using the AST abstraction and the entire functionality of Python.

In addition to the low-level abstraction of Verilog HDL, Veriloggen provides high-level abstractions to productively express a hardware structure.

  • Stream is a dataflow-based high-level synthesis layer for high-performance parallel stream processing.
  • Thread is a procedural high-level synthesis layer to express sequential behaviors, such as DMA transfers and controls.

Veriloggen is not designed for designing a hardware by programmer directly, but is for providing an efficient abstraction to develop a more efficient domain specific language and tools.

Contribute to Veriloggen

Veriloggen project always welcomes questions, bug reports, feature proposals, and pull requests on GitHub.

for questions, bug reports, and feature proposals

Please leave your comment on the issue tracker on GitHub.

for pull requests

Please check "CONTRIBUTORS.md" for the contributors who provided pull requests.

Veriloggen uses pytest for the integration testing. When you send a pull request, please include a testing example with pytest. To write a testing code, please refer the existing testing examples in "tests" directory.

If the pull request code passes all the tests successfully and has no obvious problem, it will be merged to the develop branch by the main committers.

Installation

Requirements

  • Python: 3.7.7 or later
    • Python 3.9.5 or later version is recommended for macOS with Apple Silicon.
  • Icarus Verilog: 10.1 or later
sudo apt install iverilog
  • pyverilog: 1.3.0 or later
    • pyverilog requires Jinja2. Jinja2 3.0.3 is recommended for macOS with Apple Silicon.
  • numpy: 1.17 or later
    • numpy 1.22.1 is recommended for macOS with Apple Silicon.
pip3 install pyverilog numpy

Optional installation for testing

These are required for automatic testing of tests and examples. We recommend to install these testing library to verify experimental features.

  • pytest: 3.8.1 or later
  • pytest-pythonpath: 0.7.3 or later
pip3 install pytest pytest-pythonpath

For fast RTL simulation, we recommend to install Verilator.

  • Verilator: 4.028 or later
sudo apt install verilator

Optional installation for visualization

To visualize the generated hardware by veriloggen.stream, these libraries are required.

  • graphviz: 2.38.0 or later
  • pygraphviz: 1.3.1 or later
sudo apt install graphviz
pip3 install pygraphviz

Install

Now you can install Veriloggen using setup.py script:

python3 setup.py install

Docker

Dockerfile is available. You can try Veriloggen on Docker without any installation on your host platform.

cd docker
sudo docker build -t user/veriloggen .
sudo docker run --name veriloggen -i -t user/veriloggen /bin/bash
cd veriloggen/examples/led/
make

Examples and testing

There are some exapmles in examples and various testing codes in tests. The testing codes are actually good small examples suggesting how to represent a desired function.

To run the testing codes, please type the following commands.

cd tests
python3 -m pytest .

If you use Verilator instead of Icarus Verilog for RTL simulation, set "--sim" option.

python3 -m pytest --sim=verilator .

Getting started

You can find some examples in 'veriloggen/examples/' and 'veriloggen/tests'.

Let's begin veriloggen by an example. Create a example Python script in Python as below. A blinking LED hardware is modeled in Python. Open 'hello_led.py' in the root directory.

from __future__ import absolute_import
from __future__ import print_function
import sys
import os
from veriloggen import *


def mkLed():
    m = Module('blinkled')
    width = m.Parameter('WIDTH', 8)
    clk = m.Input('CLK')
    rst = m.Input('RST')
    led = m.OutputReg('LED', width, initval=0)
    count = m.Reg('count', 32, initval=0)

    seq = Seq(m, 'seq', clk, rst)

    seq.If(count == 1024 - 1)(
        count(0)
    ).Else(
        count.inc()
    )

    seq.If(count == 1024 - 1)(
        led.inc()
    )

    seq(
        Systask('display', "LED:%d count:%d", led, count)
    )

    return m


def mkTest():
    m = Module('test')

    # target instance
    led = mkLed()

    uut = Submodule(m, led, name='uut')
    clk = uut['CLK']
    rst = uut['RST']

    simulation.setup_waveform(m, uut, m.get_vars())
    simulation.setup_clock(m, clk, hperiod=5)
    init = simulation.setup_reset(m, rst, m.make_reset(), period=100)

    init.add(
        Delay(1000 * 100),
        Systask('finish'),
    )

    return m

if __name__ == '__main__':
    test = mkTest()
    verilog = test.to_verilog(filename='tmp.v')
    #verilog = test.to_verilog()
    print(verilog)

    sim = simulation.Simulator(test)
    rslt = sim.run()
    print(rslt)

    # sim.view_waveform()

Run the script.

python3 hello_led.py

You will have a complete Verilog HDL source code named 'tmp.v' as below, which is generated by the source code generator.

module test
(

);

  localparam uut_WIDTH = 8;
  reg uut_CLK;
  reg uut_RST;
  wire [uut_WIDTH-1:0] uut_LED;

  blinkled
  uut
  (
    .CLK(uut_CLK),
    .RST(uut_RST),
    .LED(uut_LED)
  );


  initial begin
    $dumpfile("uut.vcd");
    $dumpvars(0, uut, uut_CLK, uut_RST, uut_LED);
  end


  initial begin
    uut_CLK = 0;
    forever begin
      #5 uut_CLK = !uut_CLK;
    end
  end


  initial begin
    uut_RST = 0;
    #100;
    uut_RST = 1;
    #100;
    uut_RST = 0;
    #100000;
    $finish;
  end


endmodule



module blinkled #
(
  parameter WIDTH = 8
)
(
  input CLK,
  input RST,
  output reg [WIDTH-1:0] LED
);

  reg [32-1:0] count;

  always @(posedge CLK) begin
    if(RST) begin
      count <= 0;
      LED <= 0;
    end else begin
      if(count == 1023) begin
        count <= 0;
      end else begin
        count <= count + 1;
      end
      if(count == 1023) begin
        LED <= LED + 1;
      end 
      $display("LED:%d count:%d", LED, count);
    end
  end


endmodule

You will also see the simulation result of the generated Verilog code on Icarus Verilog.

VCD info: dumpfile uut.vcd opened for output.
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  x count:         x
LED:  0 count:         0
LED:  0 count:         1
LED:  0 count:         2
LED:  0 count:         3
LED:  0 count:         4
...
LED:  9 count:       777
LED:  9 count:       778
LED:  9 count:       779
LED:  9 count:       780
LED:  9 count:       781
LED:  9 count:       782
LED:  9 count:       783

If you installed GTKwave and enable 'sim.view_waveform()' in 'hello_led.py', you can see the waveform the simulation result.

waveform.png

Veriloggen extension libraries

Mixed-paradigm high-level synthesis

  • veriloggen.thread.Thread: Procedural high-level synthesis for DMA and I/O controls
  • veriloggen.thread.Stream: Dataflow-based high-level synthesis for high-performance stream processing

Frequently-used abstractions

  • veriloggen.verilog: Verilog HDL source code synthesis and import APIs
  • veriloggen.simulation: Simulation APIs via Verilog simulators
  • veriloggen.seq: Synchronous circuit builder (Seq)
  • veriloggen.fsm: Finite state machine builder (FSM)

Please see examples and tests directories for many examples.

Related project

Pyverilog

  • Python-based Hardware Design Processing Toolkit for Verilog HDL

NNgen

  • A Fully-Customizable Hardware Synthesis Compiler for Deep Neural Network

veriloggen's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

veriloggen's Issues

Help, how to make a verilog module from a Boolean expression

Hi, I need to make a verilog module that calculates a boolean expression from an equation given as a string in python, Would you have an example of how to do this using veriloggen?
Ex:
python:
exp = A & B ^ ~C
Verilog:
module exp(input A, input B, input C, output exp);
assign exp = A & B ^ ~C;
endmodule

Case statement within combinational block

I am trying to create a case statement within a combinational block, but I am not getting the blocking assignment it should be inferred. I am getting instead a non-blocking ("<=") assignment instead.

  always @(*) begin
    case(myvar)
      0: begin
        logic_wire <= 1;
      end
      default: begin
        logic_wire <= 5;
      end
    endcase
  end

Any idea on how to get this done? This is what my code looks like

myvar= m.Reg ('myvar', width = 4 , initval = 0 )
logic_wire= m.Reg ('logic_wire', width = 1 , initval = 0 )

decCond = []
decCond.append (vg.When ( 0 ) (logic_wire ( 1 )))
# ... more conditions ...
decCond.append (vg.When () (logic_wire ( 5 )))
m.Always( ) ( vg.Case (myvar) (* decCond ) )

Thanks!

iverilog libdir option

Thanks for the great work on this module! I suggest adding support for the iverilog -y option (libdir, see http://iverilog.wikia.com/wiki/Iverilog_Flags). This makes it easy to run simulations with stub modules instantiated from existing Verilog libraries.

Here's how I implemented this modification
veriloggen/simulation/simulation.py @ line 119

if libdirs:
   for libdir in libdirs:
      cmd.append('-y')
      cmd.append(libdir)

libdirs was then passed as an optional argument through run and run_iverilog.

Convention violation of AXI Lite protocol on AxiLiteSlave

About

AxisLiteRegister now accepts outstandings of 2 in read transactions.
The axi lite protocol requires that the number of outstandings be less than 1.

Expected

Set the maximum number of outstandings for AxiLiteSlave transactions to 1.

Environment

  • Ubuntu 18.04.4 LTS
  • Python 3.8.13
  • pyverilog 1.3.0
  • veriloggen v2.1.0 - v2.1.1

Debug

I suspect that the "ack" signal generated by push_read_data() in types/axi.py:AxiLiteSlave class is not correct.
In thread/axis.py, this "ack" is observed and FSM of AXISLiteRegister is set back to init.
The "ack" signal is not a handshake notification of rdata, but rather a push notification of rdata, so it make fsm into init, despite handshake for read channel has not been established.
The fsm state returns to init even if the handshake has not been established, and the next address request is accepted.
As a result, the number of outstandings seems to be more than 1.

  • https://github.com/PyHDI/veriloggen/blame/c548d58fc6c72efaf0994682a07d0a4f52b737cf/veriloggen/types/axi.py#L1850-L1877

    def push_read_data(self, data, cond=None):
    """
    @return ack
    """
    if self._read_disabled:
    raise TypeError('Read disabled.')
    if cond is not None:
    self.seq.If(cond)
    ack = vtypes.Ors(self.rdata.rready, vtypes.Not(self.rdata.rvalid))
    self.seq.If(ack)(
    self.rdata.rdata(data),
    self.rdata.rvalid(1)
    )
    # de-assert
    self.seq.Delay(1)(
    self.rdata.rvalid(0)
    )
    # retry
    self.seq.If(vtypes.Ands(self.rdata.rvalid, vtypes.Not(self.rdata.rready)))(
    self.rdata.rvalid(self.rdata.rvalid)
    )
    return ack

  • https://github.com/PyHDI/veriloggen/blame/c548d58fc6c72efaf0994682a07d0a4f52b737cf/veriloggen/thread/axis.py#L290-L325

    init_state = fsm.current
    # read
    read_state = fsm.current + 1
    fsm.If(readvalid).goto_from(init_state, read_state)
    fsm.set_index(read_state)
    rdata = self.m.TmpWire(self.datawidth, signed=True, prefix='axislite_rdata')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.register)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    rdata.assign(rval)
    flag = self.m.TmpWire(prefix='axislite_flag')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.flag)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    flag.assign(rval)
    resetval = self.m.TmpWire(self.datawidth, signed=True, prefix='axislite_resetval')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.resetval)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    resetval.assign(rval)
    ack = self.push_read_data(rdata, cond=fsm)
    # flag reset
    state_cond = fsm.state == fsm.current
    for i, r in enumerate(self.register):
    self.seq.If(state_cond, ack, flag, maskaddr == i)(
    self.register[i](resetval),
    self.flag[i](0)
    )
    fsm.If(ack).goto_init()

realtime monitoring of simulation output

Hi,

On my platform (macOS Sierra 10.12.5, vvp 11.0, iverilog 11.0) the display=True option of simulation.run doesn't provide realtime output when using the iverilog simulator. The simulation runs, but no simulator output is printed until the simulation finishes. Such realtime feedback would be useful for running long simulations.

I traced the issue back to vvp and opened an issue there.

As workaround for now, I found that the issue can be resolved by calling vvp through unbuffer, which can be installed on macOS via brew install homebrew/dupes/expect. I believe it is standard on Linux systems.

Here is a sample implementation in simulation.run_iverilog, near line 175.

# generate the simulation command
sim_cmd = [os.path.join('.', outputfile)]
if display:
    # use unbuffer if available
    try:
        # unbuffer will print out a usage message to stderr if available, which is suppressed
        subprocess.Popen('unbuffer', stderr=subprocess.DEVNULL).wait()
        sim_cmd = ['unbuffer'] + sim_cmd
    except FileNotFoundError:
        pass

# run the simulation
sim_rslt = ''
with subprocess.Popen(sim_cmd, stdout=subprocess.PIPE) as p:
    for line in p.stdout:
        decoded = line.decode(encode)
        sim_rslt += decoded
        if display:
            print(decoded, end='')

Thanks,
Steven

Creating a combinational sequence

I do not think at the moment is possible to create Seq objects made out of combinational logic, in the same way that it is possible with sequential logic, as it is very convenient.

Example of a Seq (sequential) construct:

    seq = Seq(m, 'seq', clk, rst)
    update_cond_value = m.TmpReg(3, initval=0)
    seq( update_cond_value(sw[0:3]) )
    count = m.TmpReg(2, initval=0)
    seq( count.inc() )
    seq.make_always()

Do you guys see a point for this construct?

While statement

While statement is not supported. This will be implemented with Initial statement.

Explicit latency constraint between two stream objects which accesses to external resources outside of the stream.

thread.stream has some external operators to access outside of the stream pipeline, such as ToExtern/FromExtern, read_RAM, write_RAM. Additionally, RingBuffer and Scratchpad uses on-chip RAM as a random access buffer.

The result of such the external operators are sensitive to their read/write timings. So scheduler has to support the explicit latency constants between two (or more) linked external operators.

read_verilog_module does not support instances with unconnected ports, will generate a TypeError.

from __future__ import absolute_import
from __future__ import print_function
import sys
import os
import collections

# the next line can be removed after installation
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

from veriloggen import *

test_v = '''\
module test ();

  wire CLK, RST;
  adder u_adder (
    .clk (CLK),
    .rst (RST),
    .A   (   )    # Please pay attention to this line, as it will trigger a TypeError error, refer below.
  );
endmodule
'''


def mkLed():
    m = from_verilog.read_verilog_module_str(test_v)

    return m['test']


if __name__ == '__main__':
    test = mkLed()
    verilog = test.to_verilog()
    print(verilog)


Traceback (most recent call last):
File "projects/user/work/python3/veriloggen-develop/examples/read_verilog_code/read_verilog_code.py", line 33, in
verilog = test.to_verilog()
File "projects/user/work/python3/veriloggen-develop/veriloggen/core/module.py", line 1019, in to_verilog
return to_verilog.write_verilog(obj, filename, for_verilator)
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 20, in write_verilog
module_ast_list = [visitor.visit(mod) for mod in modules
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 20, in
module_ast_list = [visitor.visit(mod) for mod in modules
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 588, in visit
return self.visit_Module(node)
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 611, in visit_Module
items = [self.visit(i) for i in node.items
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 611, in
items = [self.visit(i) for i in node.items
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 593, in visit
return visitor(node)
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 770, in visit_Instance
portlist = [vast.PortArg(p, self.bind_visitor.visit(a))
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 770, in
portlist = [vast.PortArg(p, self.bind_visitor.visit(a))
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 54, in visit
return visitor(node)
File "projects/user/work/python3/veriloggen-develop/veriloggen/verilog/to_verilog.py", line 47, in generic_visit
raise TypeError("Type %s is not supported." % str(type(node)))
TypeError: Type <class 'NoneType'> is not supported.

Slice in Wire with two dimension

Hi, I'm trying to do the following structure in Veriloggen:

m  = Module('test')
my_wire0 = m.Wire('my_wire0',8,2)
my_wire1 = m.Output('my_wire1',2)
my_wire1.assign(my_wire0[0][0:2])
print(m.to_verilog())

But an exception is raised!

Multi instance using the same module

When doing multi instance with the same module, the module name is appended with "_" surfix. Code like:

m = Module("top")
param = []
port = []
m.Instance("counter","i0",param,port)
m.Instance("counter","i1",param,port)
print(m.to_verilog())

The result likes:

module top
(
);

counter
i0
{
};

counter_
i1
{
};

endmodule

I can't figure out why there is a "_" at the end of reference name for the second instance declaration.
Anyone has clue to this?

Thanks a lot!

always @ ( * ) combinational block

Hi, is there any example about how to get some combinational block? grepping on the examples I found something but it all is related to the test and not the generated RTL I believe?

veriloggen/examples$ grep  -r -e "always @(\*" * -l

simulation_verilator/test_simulation_verilator.py
thread_add_ipxact/test_thread_add_ipxact.py
thread_embedded_verilog_ipxact/test_thread_embedded_verilog_ipxact.py
thread_ipxact/test_thread_ipxact.py
thread_memcpy_ipxact/test_thread_memcpy_ipxact.py
thread_verilog_submodule_ipxact/test_thread_verilog_submodule_ipxact.py

In other words, what I need to get is a block of this form.

always @ ( * ) begin
end

Ideally this block would have some more logic inside, some if-else maybe.

always @ ( * ) begin
var1 = some_other_Var
if ( var1 == yet_oher_var) begin
assign_this = 1;
end
else begin
assign_this = 0;
end
end

Is this possible?

Imcompatibility of `Module.Wire` and `Module.TmpWire` regarding the keyword arguments.

When I try to switch automatically between TmpWire and Wire instead of using only Wire in codes like below (example from thread/ram.py), I thought it just works by replacing 'Wire' with 'TmpWire'.

interface = RAMInterface(m, name + '_%d' % i, datawidth, addrwidth,
                         itype='Wire', otype='Wire', with_enable=True)
# naive solution idea
# interface = RAMInterface(m, name + '_%d' % i, datawidth, addrwidth,
#                          itype='TmpWire', otype='TmpWire', with_enable=True)

However, the alternation ended up outputting verilog code like blow (comments are mine).

// expected verilog output
// wire [8-1:0] _tmp_50;
// actual verilog output
wire ["myram_addr"-1:0] _tmp_50 [0:8-1];

It seems that this happend since the keyword argument name of Wire was interpreted as width in TmpWire.

Java runtime error

is:open is:issue When I give the comment on mac terminal "sudo apt install iverilog" it gives The operation couldn’t be completed. Unable to locate a Java Runtime that supports apt. Please visit http://www.java.com for information on installing Java. I tried downloading from Homebrew Icarus-verilog, unable to find the file. I tried pasting the setup.py command it throws an error saying directory or file not found. Please help

`types.AxiMaster` should be have a cap of number of outstanding readout transactions.

About

We are currently using ARM's official AXI Protocol Checker which is AMBA 4 AXI4,AXI4-lite,AXI4-stream SVAs (BP063) to verify IP that is using veriloggen.AxiMaster.

veriloggen.types.AxiMaster can only specify the upper limit of the number of write transaction transfers
by the outstanding_wcount_width of the write transaction, so the upper limit of the number of read transaction transfers is nondeterministic. This causes the simulator to fail in some cases.

   Axi4PC    // ARM Official Protocol Checker IP
      #(
         .DATA_WIDTH       ( AXI4_DW ),
         .WID_WIDTH        ( 0       ),
         .RID_WIDTH        ( 0       ),
         .AWUSER_WIDTH     ( 2       ),
         .WUSER_WIDTH      ( 0       ),
         .BUSER_WIDTH      ( 0       ),
         .ARUSER_WIDTH     ( 2       ),
         .RUSER_WIDTH      ( 0       ),
         .MAXRBURSTS       ( 1       ),    // <- We want to set this argument correctly.
         .MAXWBURSTS       ( 7       ),
         .MAXWAITS         ( 33      )
      )
      Axi4PC
      (
         // Global Signals
         .ACLK          ( clk           ),
         .ARESETn       ( rst_n         ),
         // Write Address Channel
         .AWID          ( maxi_awid     ),
         .AWADDR        ( maxi_awaddr   ),
         .AWLEN         ( maxi_awlen    ),
         .AWSIZE        ( maxi_awsize   ),
         .AWBURST       ( maxi_awburst  ),
         .AWLOCK        ( maxi_awlock   ),
         .AWCACHE       ( maxi_awcache  ),
         .AWPROT        ( maxi_awprot   ),
         .AWQOS         ( maxi_awqos    ),
         .AWREGION      ( maxi_awregion ),
         .AWUSER        ( maxi_awuser   ),
         .AWVALID       ( maxi_awvalid  ),
         .AWREADY       ( maxi_awready  ),
         // Write Channel
         .WLAST         ( maxi_wlast    ),
         .WDATA         ( maxi_wdata    ),
         .WSTRB         ( maxi_wstrb    ),
         .WUSER         ( maxi_wuser    ),
         .WVALID        ( maxi_wvalid   ),
         .WREADY        ( maxi_wready   ),
         // Write Response Channel
         .BID           ( maxi_bid      ),
         .BRESP         ( maxi_bresp    ),
         .BUSER         ( maxi_buser    ),
         .BVALID        ( maxi_bvalid   ),
         .BREADY        ( maxi_bready   ),
         // Read Address Channel
         .ARID          ( maxi_arid     ),
         .ARADDR        ( maxi_araddr   ),
         .ARLEN         ( maxi_arlen    ),
         .ARSIZE        ( maxi_arsize   ),
         .ARBURST       ( maxi_arburst  ),
         .ARLOCK        ( maxi_arlock   ),
         .ARCACHE       ( maxi_arcache  ),
         .ARPROT        ( maxi_arprot   ),
         .ARQOS         ( maxi_arqos    ),
         .ARREGION      ( maxi_arregion ),
         .ARUSER        ( maxi_aruser   ),
         .ARVALID       ( maxi_arvalid  ),
         .ARREADY       ( maxi_arready  ),
         // Read Channel
         .RID           ( maxi_rid      ),
         .RLAST         ( maxi_rlast    ),
         .RDATA         ( maxi_rdata    ),
         .RRESP         ( maxi_rresp    ),
         .RUSER         ( maxi_ruser    ),
         .RVALID        ( maxi_rvalid   ),
         .RREADY        ( maxi_rready   ),
         // Low power interface
         .CACTIVE       ( 1'b1          ),
         .CSYSREQ       ( 1'b1          ),
         .CSYSACK       ( 1'b1          )
   );

Expected

Set a cap on the number of outstanding read transactions for veriloggen.types.AxiMaster .

Environment

  • Ubuntu 18.04.4 LTS
  • Python 3.8.13
  • pyverilog 1.3.0
  • veriloggen v2.1.0 - v2.1.1

Creating input with literal BW in the form of [n:0] instead of [n-1:0]

I am using a python list comprehension to create on the fly the inputs ports for my module.

inputs = [m.Input (str(name), bw) for name,bw in ports_dict]

Where ports_dict is a dict of this shape: {'one_port_name_of_bw_3' : 3, 'other_port_of_bw_1' : 1, ... }

I would expect the m.Input class to have these written out as

input [2:0] one_port_name_of_bw_3,
input       other_port_of_bw_1

Instead I am having

input [2-1:0] one_port_name_of_bw_3,
input  [1-1:0] other_port_of_bw_1

Input class inherits from _Variable, which is defined as

class _Variable(_Numeric):

    def __init__(self, width=1, dims=None, signed=False, value=None, initval=None, name=None,
                 raw_width=None, raw_dims=None, module=None):

Tried some of these extra args but I do not think any of them allow for this funcionality? raw_width looks like what I want but I could not get it to work. The idea would be maybe to pass a tuple (2:0) and so have a [2:0] bitwidth? Hmm, wait, but what would happen with the 1 value then? Anyway you get my point, maybe this is already implemented somehow and I am missing it

Thanks!

Support for SystemVerilog Interfaces

I think veriloggen does not support SV interfaces at the moment?

Are these on the pipeline? It should not be too much of an update to add suport for them given the syntax and structure is pretty similar to an usual verilog module

Thanks

Supporting indirect addressing by sink RAM of Thread.Stream

Let's support the sink (write) mode with Indirect addressing like this:

# Stream definition
strm = vthread.Stream(m, 'mystream', clk, rst)
data = ... 
addr = ...
strm.sink(data, 'data')
strm.sink(addr, 'addr')

# Thread definition
def ctrl():
    # ...
    strm.set_sink_indirect('data', 'addr', ram, size)

Help with design of low-level HDL language

FPGA world suffers a lot from fragmentation - some tools produce Verilog, some VHDL, some - only subsets of them, creating low-level LLVM-like alternative will help everyone, so HDL implementations will opt only for generating this low-level HDL and routing/synthesizers accept it. LLVM or WebAssembly - you can see how many languages and targets are supported now by both. With more open source tools for FPGA this is more feasible now than ever. Most of the people suggest to adapt FIRRTL for this. Please check the discussion and provide a feedback if you have any. There is a good paper on FIRRTL design and its reusability across different tools and frameworks.

See f4pga/ideas#19

# The task call part in veriloggen library is not generated correctly

When you run the following, the task call part is not generated as expected

import veriloggen as vg

module = vg.Module("task_module")

clk = module.Input("CLK")
a = module.Input("a")
init_task = vg.Task("init")
init_task.Input("a")
init_task.Body()

module.add_task(init_task)
module.Always(vg.Posedge(clk))(
    init_task.call(a)
)

print(module.to_verilog())
module task_module
(
  input CLK,
  input a
);


  task init;
    input a;
    begin
    end
  endtask


  always @(posedge CLK) begin
    inita //init(a); is expected
  end


endmodule

my environment

  - python==3.12
  - pip==23.2.1
  - pip:
      - jinja2==3.1.2
      - markupsafe==2.1.3
      - numpy==1.26.2
      - ply==3.11
      - pyverilog==1.3.0
      - veriloggen==2.3.0

Better Documentation/Tutorials

So the examples are useful for somethings but say if I want to have nested if statements or make something that generates this verilog:

reg signed [width:0] x [0:width-1];
always @(posedge clock) begin
    x[0] <= 0
end

I've found myself doing a lot of trial and error, reading the source and scouring the existing examples trying to find something that would use these constructs (it's not always obvious from the example names).

Also, both these issues are still unresolved for me. I'm trying to write a coregen script to generate a cordic IP block.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.