Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _build(self, addr, data, enable):
""" Builds a write port. """
if self.max_write_ports is not None:
self.write_ports += 1
if self.write_ports > self.max_write_ports:
raise PyrtlError('maximum number of write ports (%d) exceeded' %
self.max_write_ports)
writeport_net = LogicNet(
op='@',
op_param=(self.id, self),
args=(addr, data, enable),
dests=tuple())
working_block().add_net(writeport_net)
self.writeport_nets.append(writeport_net)
return self
elif numext < 0:
raise PyrtlError(
'Neither zero_extended nor sign_extended can'
' reduce the number of bits')
else:
from .corecircuits import concat
if isinstance(extbit, int):
extbit = Const(extbit, bitwidth=1)
extvector = WireVector(bitwidth=numext)
net = LogicNet(
op='s',
op_param=(0,)*numext,
args=(extbit,),
dests=(extvector,))
working_block().add_net(net)
return concat(extvector, self)
def _build(self, other):
# Actually create and add wirevector to logic block
# This might be called immediately from ilshift, or delayed from conditional assignment
net = LogicNet(
op='w',
op_param=None,
args=(other,),
dests=(self,))
working_block().add_net(net)
def net_transform(transform_func, block=None, **kwargs):
"""
Maps nets to new sets of nets according to a custom function
:param transform_func:
Function signature: func(orig_net (logicnet)) -> keep_orig_net (bool)
:return:
"""
block = working_block(block)
with set_working_block(block, True):
for net in block.logic.copy():
keep_orig_net = transform_func(net, **kwargs)
if not keep_orig_net:
block.logic.remove(net)
def __init__(self, bitwidth=None, name='', block=None):
""" Construct a generic WireVector
:param int bitwidth: If no bitwidth is provided, it will be set to the
minimum number of bits to represent this wire
:param Block block: The block under which the wire should be placed.
Defaults to the working block
:param String name: The name of the wire referred to in some places.
Must be unique. If none is provided, one will be autogenerated
:return: a wirevector object representing a const wire
"""
self._name = None
# used only to verify the one to one relationship of wires and blocks
self._block = working_block(block)
self.name = next_tempvar_name(name)
self._validate_bitwidth(bitwidth)
if core._setting_keep_wirevector_call_stack:
import traceback
self.init_call_stack = traceback.format_stack()
def find_loop(block=None):
block = working_block(block)
block.sanity_check() # make sure that the block is sane first
result = _check_for_loop(block)
if not result:
return
wires_left, logic_left = result
import random
class _FilteringState(object):
def __init__(self, dst_w):
self.dst_w = dst_w
self.arg_num = -1
def dead_end():
# clean up after a wire is found to not be part of the loop
wires_left.discard(cur_item.dst_w)
concat( msb, lsb )
"""
if len(args) <= 0:
raise PyrtlError('error, concat requires at least 1 argument')
if len(args) == 1:
return as_wires(args[0])
arg_wirevectors = tuple(as_wires(arg) for arg in args)
final_width = sum(len(arg) for arg in arg_wirevectors)
outwire = WireVector(bitwidth=final_width)
net = LogicNet(
op='c',
op_param=None,
args=arg_wirevectors,
dests=(outwire,))
working_block().add_net(net)
return outwire
one bit as well). The two exceptions are for inputs/outputs (so that
we can keep the same interface) which are immediately broken down into
the individual bits and memories. Memories (read and write ports) which
require the reassembly and disassembly of the wirevectors immediately
before and after. There arethe only two places where 'c' and 's' ops
should exist.
The block that results from synthesis is actually of type
"PostSynthesisBlock" which contains a mapping from the original inputs
and outputs to the inputs and outputs of this block. This is used during
simulation to map the input/outputs so that the same testbench can be
used both pre and post synthesis (see documentation for Simulation for
more details).
"""
block_pre = working_block(block)
block_pre.sanity_check() # before going further, make sure that pressynth is valid
block_in = copy_block(block_pre, update_working_block=False)
block_out = PostSynthBlock()
# resulting block should only have one of a restricted set of net ops
block_out.legal_ops = set('~&|^nrwcsm@')
wirevector_map = {} # map from (vector,index) -> new_wire
with set_working_block(block_out, no_sanity_check=True):
# First, replace advanced operators with simpler ones
for op, fun in [
('*', _basic_mult),
('+', _basic_add),
('-', _basic_sub),
('x', _basic_select),
('=', _basic_eq),
def output_to_verilog(dest_file, block=None):
""" A function to walk the block and output it in verilog format to the open file. """
block = working_block(block)
file = dest_file
internal_names = _VerilogSanitizer('_verout_tmp_')
for wire in block.wirevector_set:
internal_names.make_valid_string(wire.name)
def varname(wire):
return internal_names[wire.name]
_to_verilog_header(file, block, varname)
_to_verilog_combinational(file, block, varname)
_to_verilog_sequential(file, block, varname)
_to_verilog_memories(file, block, varname)
_to_verilog_footer(file)