verilog

Lots of code in this file could be shared between methods and the VerilogInstance/Module classes. Maybe distill at some point.

class verilog.AXI4LiteDevice(regname, nbytes, mode, hdl_suffix='', hdl_candr_suffix='', memory_map=[], typecode=255, data_width=32, axi4lite_mode='')[source]

A class to encapsulate the parameters (name, size, etc.) of a AXI4-Lite slave device.

__init__(regname, nbytes, mode, hdl_suffix='', hdl_candr_suffix='', memory_map=[], typecode=255, data_width=32, axi4lite_mode='')[source]

Class constructor.

Parameters:
  • regname (String) – Name of register (this name is the string used to access the register from software).
  • nbytes (Integer) – Number of bytes in this slave’s memory space.
  • mode (String) – Permissions (‘r’: readable, ‘w’: writable, ‘rw’: read/writeable).
  • hdl_suffix (String) – Suffix given to wishbone port names. Eg. if hdl_suffix = foo, ports have the form wbs_dat_i_foo.
  • hdl_candr_suffix (String) – Suffix given to wishbone clock and reset port names. Eg. if hdl_suffix = foo, ports have the form wbs_clk_i_foo.
  • memory_map (list) – A list or Register instances defining the contents of sub-blocks of this device’s memory.
  • typecode (Integer) – Typecode number (0-255) identifying the type of this block. See yellow_block_typecodes.py.
  • data_width (Integer) – Width of the data to be stored in this device.
  • axi4lite_mode (String) – Mode of the axi4lite interface. Eg. axi4lite_mode = ‘raw’, instantiates a raw axi4lite device.
base_addr = None

Start (lowest) address of the memory space used by this device, in bytes.

high_addr = None

End (highest) address of the memory space used by this device, in bytes.

class verilog.ImmutableWithComments[source]

A class which you can add attributes to, but you can’t change them once they’re set. You are allowed to try and set them to the same value again. The comment attribute is special. Each time you try to set it, the comment string is appended to the existing comment attribute.

__init__()[source]

Initialize self. See help(type(self)) for accurate signature.

class verilog.Parameter(name, value, comment=None)[source]

A simple class to hold parameter attributes. It is immutable, and will throw an error if its attributes are changed after being set.

__init__(name, value, comment=None)[source]

Create a Parameter instance.

Parameters:
  • name (str) – Name of this parameter
  • value (Varies) – Value this parameter should be set to.
  • comment (str) – User-assisting comment string to attach to this parameter.
update_attrs(name, value, comment=None)[source]

Update the attributes of this block.

Parameters:
  • name (str) – Name of this parameter
  • value (Varies) – Value this parameter should be set to.
  • comment (str) – User-assisting comment string to attach to this parameter.
class verilog.Port(name, signal=None, parent_port=False, parent_sig=True, width=0, **kwargs)[source]

A simple class to hold port attributes. It is immutable, and will throw an error if multiple manipulation attempts are incompatible.

__init__(name, signal=None, parent_port=False, parent_sig=True, width=0, **kwargs)[source]

Create a Port instance.

Parameters:
  • name – Name of the port
  • signal (str) – Signal to which this port is attached
  • parent_port (bool) – When module ‘A’ instantiates the module to which this port is attached, should this port be connected to a similar port on ‘A’.
  • parent_sig (bool) – When module ‘A’ instantiates the module to which this port is attached, should ‘A’ also instantiate a signal matching the one connected to this port.
  • width (bool) – Bitwidth of the port (0 for non-vector ports)
  • kwargs – Other keywords which should become attributes of this instance.
update_attrs(name, signal=None, parent_port=False, parent_sig=True, width=0, **kwargs)[source]

Update the attributes of this block.

Parameters:
  • name – Name of the port
  • signal (str) – Signal to which this port is attached
  • parent_port (bool) – When module ‘A’ instantiates the module to which this port is attached, should this port be connected to a similar port on ‘A’.
  • parent_sig (bool) – When module ‘A’ instantiates the module to which this port is attached, should ‘A’ also instantiate a signal matching the one connected to this port.
  • width (bool) – Bitwidth of the port (0 for non-vector ports)
  • kwargs – Other keywords which should become attributes of this instance.
class verilog.Signal(name, signal='', width=0, **kwargs)[source]

A simple class to hold signal attributes. It is immutable, and will throw an error if its attributes are changed after being set.

__init__(name, signal='', width=0, **kwargs)[source]

Create a ‘Signal’ instance.

Parameters:
  • name (str) – Name of this signal
  • signal (int) – Name of this signal
  • width – Bitwidth of this signal
  • kwargs – Other keywords which should become attributes of this instance.
update_attrs(name, width=0, **kwargs)[source]
class verilog.VerilogModule(name='', topfile=None, comment='')[source]

A Python object which knows how to represent itself in Verilog.

__init__(name='', topfile=None, comment='')[source]

Construct a new module, named name. You can either start with an empty module and add ports/signals/instances to it, or you can specify an existing top-level file topfile, which will be modified. If doing the latter, the construction of wishbone interconnect demands that the topfile has a localparam N_WB_SLAVES, which specifies the number of wishbone slaves in the un-modified topfile. And SLAVE_BASE and SLAVE_HIGH localparams definiting the slave addresses.

Eg:

localparam N_WB_SLAVES = 2;

localparam SLAVE_BASE = {
32'h00010000, // slave_1
32'h00000000  // slave_0
};

localparam SLAVE_HIGH = {
32'h00010003, // slave_1
32'hFFFFFFFF  // slave_0
};

// This module will only tolerate
// i/o declarations like:

module top (
    input sysclk_n,
    input sysclk_p,
    ...
    );

// I.e, NOT

module top(
    sysclk_n,
    sysclk_p,
    ...
    );
    input sysclk_n;
    input sysclk_p;
    ...

// YMMV if your topfile doesn't use linebreaks as
// shown above. I.e., for best chance of success don't do

module top( sysclk_n,
sysclk_p);

localparam SLAVE_BASE = {32'h00000000};
Parameters:
  • name (str) – Name of this module
  • topfile (str or None) – The filename of an existing verilog file, if any, to which this module should add.
  • comment (str) – A user-friendly comment to be inserted in Verilog where this module is instantiated.
add_axi4lite_interface(regname, mode, nbytes=4, default_val=0, suffix='', candr_suffix='', memory_map=[], typecode=255, data_width=32, axi4lite_mode='')[source]

Add the ports necessary for a AXI4-Lite slave interface.

This function returns the AXI4LiteDevice object, so the caller can mess with it’s memory map if they so desire.

Added the (optional) data_width parameter to make provision for variable-size BRAMs. Added the (optional) axi4lite_mode parameter. Eg. axi4lite_mode = ‘raw’ instantiates a raw axi4lite device.

Parameters:
  • regname (String) – Name of register (this name is the string used to access the register from software).
  • nbytes (Integer) – Number of bytes in this slave’s memory space.
  • mode (String) – Permissions (‘r’: readable, ‘w’: writable, ‘rw’: read/writeable).
  • suffix (String) – Suffix given to port names.
  • candr_suffix (String) – Suffix given to clock and reset port names.
  • memory_map (list) – A list or Register instances defining the contents of sub-blocks of this device’s memory.
  • typecode (Integer) – Typecode number (0-255) identifying the type of this block. See yellow_block_typecodes.py.
  • data_width (Integer) – Width of the data to be stored in this device.
  • axi4lite_mode (String) – Mode of the axi4lite interface. Eg. axi4lite_mode = ‘raw’, instantiates a raw axi4lite device.
add_axi_interface(regname, mode, nbytes=4, default_val=0, suffix='', candr_suffix='', memory_map=[], typecode=255, data_width=32, axi4lite_mode='')[source]
add_localparam(name, value, comment=None)[source]

Add a parameter to the entity, with name parameter and value value.

You may add a comment that will end up in the generated verilog.

add_parameter(name, value, comment=None)[source]

Add a parameter to the entity, with name parameter and value value.

You may add a comment that will end up in the generated verilog.

add_port(name, signal=None, parent_port=False, parent_sig=True, width=0, **kwargs)[source]

Add a port to the module. Only the parameter name is compulsory. Others may be required when instantiating this module in another.

E.g., an instance of this module needs all ports to have a defined signal value.

However, if this module is at the top level, this isn’t necessary. Similarly, a port featuring in an instantiated module need not have a width or direction specified, but if you want to instantiate the module and propagate the port to the parent, the parent won’t know what to do unless these port parameters are specified.

Parameters:
  • name – name of the port
  • signal – name of the signal to connect port to. Can include bit indexing, e.g. my_signal[15:8]
  • dir – direction of signal
  • width – width of signal
  • parent_port – When instantiating this module, promote this port to a port of the parent
  • parent_sig – When instantiating this module, add a signal named signal to the parent
  • comment – Use this to add a comment string which will end up in the generated verilog
add_raw_string(s)[source]
add_rfdc_interface(regname, mode, nbytes=4, default_val=0, suffix='', candr_suffix='', memory_map=[], typecode=255)[source]

Add the ports necessary for rfdc core, which is a special AXILite4 device

This function returns the AXI4LiteDevice object, so the caller can mess with it’s memory map if they so desire.

add_signal(name, width=0, **kwargs)[source]

Add an internal signal to the entity, with name signal and width width.

You may add a comment that will end up in the generated verilog using the comment kwarg. You may add special compiler directives using the attributes kwarg.

For example, attributes={‘keep’:‘“true”’} will generate a wire with a (* keep = “true” *) prefix
add_sourcefile(file)[source]
add_wb_interface(regname, mode, nbytes=4, suffix='', candr_suffix='', memory_map=[], typecode=255, req_offset=-1)[source]

Add the ports necessary for a wishbone slave interface. Wishbone ports that depend on the slave index are identified by a parameter that matches the instance name. This parameter must be given a value in a higher level of the verilog code!

This function returns the WbDevice object, so the caller can mess with it’s memory map if they so desire.

add_xil_axi4lite_interface(regname, mode, nbytes=4, default_val=0, suffix='', candr_suffix='', memory_map=[], typecode=255)[source]

Add the ports necessary for xilinx axi4lite cores, which are not casper AXILite4 devices

This function returns the AXI4LiteDevice object, so the caller can mess with it’s memory map if they so desire.

assign_signal(lhs, rhs, comment=None)[source]

Assign one signal to another, or one signal to a port.

i.e., generate lines of verilog like: assign lhs = rhs;

lhs and rhs are strings that can represent port or signal names, and may include verilog-style indexing, eg [15:8]

You may add a comment that will end up in the generated verilog.

assign_wb_interface(name, id=0, suffix='', candr_suffix='', sub_arb_id=0)[source]

Add the ports necessary for a wishbone slave interface. Wishbone ports that depend on the slave index are identified by a parameter that matches the instance name. This parameter must be given a value in a higher level of the verilog code!

axi4lite_memory_map(base_addr=65536, alignment=4)[source]

This function is only to be called by the ‘top’ verilog module after all other yellow blocks have called ‘modify_top’, but before the axi4lite_interconnect yellow block class has called ‘modify_top’ as that class requires the memory map this creates.

Parameters:
  • base_addr (int) – The address from which indexing of instance axi4lite interfaces will begin. Any memory space required by the template verilog file should be below this address.
  • alignment (int) – Alignment required by all memory start addresses.

memory map: keys: name of AXI4-Lite interfaces. values:

  • ‘memory_map’: internal memory map for this interface
  • ‘size’: size of internal memory map in bytes
  • ‘absolute_address’: actual address in memory determined by base_addr
  • ‘relative_address’: address relative to base_addr
  • ‘axi4lite_devices’: List of AXI4LiteDevice objects for core_info backwards compatibility
gen_assignments_ascii_art()[source]
Returns:Pretty ascii art “Assignments” string.
gen_assignments_str()[source]

Generate the verilog code required to assign a port or signal to another signal

gen_cur_blk_comment(cur_blk, dict)[source]

This helper function returns the current block string, if the dictionary is not empty and the current block is not default.

gen_default_nettype_str()[source]
gen_endmod_str()[source]
gen_instance_verilog(instname)[source]

Generate a string corresponding to the instantiation of this instance, with instance name instname

gen_instances_ascii_art()[source]
Returns:Pretty ascii art “Instances” string.
gen_instances_dec_str()[source]

Generate the verilog code required to instantiate the instances in this module

gen_localparams_dec_str()[source]

Generate the verilog code required to declare localparams

gen_mod_dec_str()[source]

Generate the verilog code required to start a module declaration.

gen_module_file(filename=None)[source]
gen_params_dec_str()[source]

Generate the verilog code required to declare parameters

gen_port_list()[source]

Generate the verilog code required to declare ports

gen_ports_dec_str()[source]

Generate the verilog code required to declare ports with special attributes, eg LOCS, etc.

gen_signals_ascii_art()[source]
Returns:Pretty ascii art “Signals” string.
gen_signals_dec_str()[source]

Generate the verilog code required to declare signals

gen_top_mod()[source]

Return the code that needs to go in a top level verilog file to incorporate this module.

I.e., everything except the module port declaration headers and endmodule lines.

TODO: This is almost identical to write_new_module_file(). Combine?

get_base_wb_slaves()[source]

Look for the pattern localparam N_WB_SLAVES in this module’s topfile, and use it to extract the number of wishbone slaves in the module. Update the base_wb_slaves attribute accordingly. Also extract the addresses. Names are auto-generated

get_instance(entity, name, comment=None)[source]

Instantiate and return a new instance of entity entity, with instance name name.

You may add a comment that will end up in the generated verilog.

has_instance(name)[source]

Check if this module has an instance called <name>. If so return True

instantiate_child_ports()[source]

Add ports and signals associated with child instances

rewrite_module_file(filename=None)[source]

Rewrite the intially supplied verilog file to include instance, signals, ports, assignments and wishbone interfaces added programmatically.

The initial verilog file is backed up with a ‘.base’ extension.

search_dict_for_name(dict, name)[source]

This helper function searches each top level dictionary to see if it contains name and returns the key that does.

set_cur_blk(cur_blk)[source]

Set the name of the block currently driving code generation. This is useful for grouping and commenting the ports / instances / signals associated with particular instances, so that the output Verilog is prettier.

Parameters:cur_blk (str) – The name of the current block driving code generation.
wb_compute(base_addr=65536, alignment=4)[source]

Compute the appropriate wishbone address limits, based on the current wishbone-using instances instantiated in the module.

Will NOT take into account wishbone memory space used by the template verilog file (but see base_addr, below)

Parameters:
  • base_addr (int) – The address from which indexing of instance wishbone interfaces will begin. Any memory space required by the template verilog file should be below this address.
  • alignment (int) – Alignment required by all memory start addresses.
write_new_module_file(filename=None)[source]

Write a verilog file from scratch, based on the programmatic additions of instances / signals / etc. to the VerilogModule instance.

The jasper toolflow has been using rewrite_module_file() rather than this method, so it may or may not still work correctly. It used to, at least…

class verilog.WbDevice(regname, nbytes, mode, hdl_suffix='', hdl_candr_suffix='', memory_map=[], typecode=255, req_offset=-1, id='')[source]

A class to encapsulate the parameters (name, size, etc.) of a wishbone slave device.

__init__(regname, nbytes, mode, hdl_suffix='', hdl_candr_suffix='', memory_map=[], typecode=255, req_offset=-1, id='')[source]

Class constructor.

Parameters:
  • regname (str) – Name of register (this name is the string used to access the register from software)
  • nbytes (int) – Number of bytes in this slave’s memory space.
  • mode (str) – Permissions (‘r’: readable, ‘w’: writable, ‘rw’: read/writeable)
  • hdl_suffix (str) – Suffix given to wishbone port names. Eg. if hdl_suffix = foo, ports have the form wbs_dat_i_foo
  • hdl_candr_suffix (str) – Suffix given to wishbone clock and reset port names. Eg. if hdl_suffix = foo, ports have the form wbs_clk_i_foo
  • memory_map (list) – A list or Register instances defining the contents of sub-blocks of this device’s memory.
  • typecode (int or hex) – Typecode number (0-255) identifying the type of this block. See yellow_block_typecodes.py
  • req_offset – Requsted offset (0-0xFFFFFFF) used to request a particular address on the memory map, please only use this if really requred``
base_addr = None

Start (lowest) address of the memory space used by this device, in bytes.

high_addr = None

End (highest) address of the memory space used by this device, in bytes.

sub_arb_id = None

If using multiple bus arbiters, which arbiter should this slave attach to?

verilog.gen_wbs_master_arbiter(arbiters, max_devices_per_arb=32)[source]

Deliver a string defining the top level of a hierarchical Wishbone arbiter. This can be written to a file and then imported into an HDL project. Ideally (maybe) this instantiation would be made via a VerilogModule class.

verilog.instantiate_wb_arb_module(module, n_slaves, n_sub_arbs=None)[source]

Instantiate a Wishbone Arbiter into a module.

Parameters:
  • module (VerilogModule instance) – Module into which the arbiter should be instantiated.
  • n_slaves (int) – Number of slaves this arbiter is connected to.
  • n_sub_arbs (int or None) – Number of sub-arbiters beneath the arbiter being instantiated here. If None, a non-hierarchical arbiter will be used.
verilog.wrap_instance(wrapper_name, instance)[source]