pyhdi / veriloggen Goto Github PK
View Code? Open in Web Editor NEWVeriloggen: A Mixed-Paradigm Hardware Construction Framework
License: Apache License 2.0
Veriloggen: A Mixed-Paradigm Hardware Construction Framework
License: Apache License 2.0
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.
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
I'm requesting to make it possible to treat Block RAM explicitly in veriloggen. I want to create line-buffer which is composed of register and BRAM.
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
.
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
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 is not supported. This will be implemented with Initial statement.
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?
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
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
"tyep"
git grep -n tyep
stypes.py:52: raise TypeError("'name' must be str, not '%s'" % str(tyep(name)))
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
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)
Verilog output file has two empty lines before the module
keyword
('\n'
'\n'
'module blinkled #\n'
'(\n'
' parameter WIDTH = 8\n'
')\n'
'(\n'
' input CLK,\n'
' input RST,\n'
' output reg [WIDTH-1:0] LED\n'
');\n'
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!
I'm requesting to support AXI Stream interface in veriloggen. It might be useful to design stream architecture.
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?
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.
AxisLiteRegister now accepts outstandings of 2 in read transactions.
The axi lite protocol requires that the number of outstandings be less than 1.
Set the maximum number of outstandings for AxiLiteSlave transactions to 1.
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.
veriloggen/veriloggen/types/axi.py
Lines 1850 to 1877 in c548d58
veriloggen/veriloggen/thread/axis.py
Lines 290 to 325 in c548d58
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.
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!
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 )
);
Set a cap on the number of outstanding read transactions for veriloggen.types.AxiMaster
.
Hi,
I am trying to use this package for creating IPXACTS from verilog files. Can it be done? If so, is it by from_verilog function or somehow?
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.
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!
I think Indirect access RAM can be realized based on stream.LUT.
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!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.