Code Monkey home page Code Monkey logo

veriloggen's People

Contributors

ryusukeyamano avatar sh-mug avatar shtaxxx avatar smilengineer avatar

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

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.

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

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.

# 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

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

While statement

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

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?

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

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

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

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)

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!

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?

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()

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.

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!

`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

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.

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!

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!

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.