Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _to_verilog_combinational(file, block, varname):
""" Print the combinational logic of the verilog implementation. """
print(' // Combinational', file=file)
# assign constants (these could be folded for readability later)
for const in block.wirevector_subset(Const):
print(' assign {:s} = {:d};'.format(varname(const), const.val), file=file)
# walk the block and output combination logic
for net in block.logic:
if net.op in 'w~': # unary ops
opstr = '' if net.op == 'w' else net.op
t = (varname(net.dests[0]), opstr, varname(net.args[0]))
print(' assign %s = %s%s;' % t, file=file)
elif net.op in '&|^+-*<>': # binary ops
t = (varname(net.dests[0]), varname(net.args[0]),
net.op, varname(net.args[1]))
print(' assign %s = %s %s %s;' % t, file=file)
elif net.op == '=':
t = (varname(net.dests[0]), varname(net.args[0]),
varname(net.args[1]))
print(' assign %s = %s == %s;' % t, file=file)
# write out all the implicit stuff
f.write("circuit Example : \n")
f.write(" module Example : \n")
f.write(" input clock : Clock\n input reset : UInt<1>\n")
# write out IO signals, wires and registers
wireRegDefs = ""
for wire in list(block.wirevector_subset()):
if type(wire) == pyrtl.wire.Input:
f.write(" input %s : UInt<%d>\n" % (wire.name, wire.bitwidth))
elif type(wire) == pyrtl.wire.Output:
f.write(" output %s : UInt<%d>\n" % (wire.name, wire.bitwidth))
elif type(wire) == pyrtl.wire.WireVector:
wireRegDefs += " wire {} : UInt<{}>\n".format(wire.name, wire.bitwidth)
elif type(wire) == pyrtl.wire.Register:
wireRegDefs += " reg {} : UInt<{}>, clock\n".format(wire.name, wire.bitwidth)
elif type(wire) == pyrtl.wire.Const:
# some const is in the form like const_0_1'b1, is this legal operation?
wire.name = wire.name.split("'").pop(0)
wireRegDefs += " node {} = UInt<{}>({})\n".format(wire.name, wire.bitwidth, wire.val)
else:
return 1
f.write(wireRegDefs)
f.write("\n")
# write "Main"
node_cntr = 0
initializedMem = []
for log_net in list(block.logic_subset()):
if log_net.op == '&':
f.write(" %s <= and(%s, %s)\n" % (log_net.dests[0].name, log_net.args[0].name,
log_net.args[1].name))
def _extend_with_bit(self, bitwidth, extbit):
numext = bitwidth - self.bitwidth
if numext == 0:
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)
:param default_value: is the value that all unspecified registers and memories will
default to. If no default_value is specified, it will use the value stored in the
object (default to 0)
"""
if default_value is None:
default_value = self.default_value
# set registers to their values
reg_set = self.block.wirevector_subset(Register)
if register_value_map is not None:
for r in reg_set:
self.value[r] = self.regvalue[r] = register_value_map.get(r, default_value)
# set constants to their set values
for w in self.block.wirevector_subset(Const):
self.value[w] = w.val
assert isinstance(w.val, numbers.Integral) # for now
# set memories to their passed values
for mem_net in self.block.logic_subset('m@'):
memid = mem_net.op_param[1].id
if memid not in self.memvalue:
self.memvalue[memid] = {}
if memory_value_map is not None:
for (mem, mem_map) in memory_value_map.items():
if isinstance(mem, RomBlock):
raise PyrtlError('error, one or more of the memories in the map is a RomBlock')
if isinstance(self.block, PostSynthBlock):
mem = self.block.mem_map[mem] # pylint: disable=maybe-no-member
def extract_cover(command):
netio = command['namesignal_list']
if len(command['cover_list']) == 0:
output_wire = twire(netio[0])
output_wire <<= Const(0, bitwidth=1, block=block) # const "FALSE"
elif command['cover_list'].asList() == ['1']:
output_wire = twire(netio[0])
output_wire <<= Const(1, bitwidth=1, block=block) # const "TRUE"
elif command['cover_list'].asList() == ['1', '1']:
# Populate clock list if one input is already a clock
if(netio[1] in clk_set):
clk_set.add(netio[0])
elif(netio[0] in clk_set):
clk_set.add(netio[1])
else:
output_wire = twire(netio[1])
output_wire <<= twire(netio[0]) # simple wire
elif command['cover_list'].asList() == ['0', '1']:
output_wire = twire(netio[1])
output_wire <<= ~ twire(netio[0]) # not gate
elif command['cover_list'].asList() == ['11', '1']:
def clone_wire(old_wire, name=None):
"""
Makes a copy of any existing wire
:param old_wire: The wire to clone
:param name: a name fo rhte new wire
Note that this function is mainly intended to be used when the
two wires are from different blocks. Making two wires with the
same name in the same block is not allowed
"""
if isinstance(old_wire, Const):
return Const(old_wire.val, old_wire.bitwidth)
else:
if name is None:
return old_wire.__class__(old_wire.bitwidth, name=old_wire.name)
return old_wire.__class__(old_wire.bitwidth, name=name)
def clone_wire(old_wire, name=None):
"""
Makes a copy of any existing wire
:param old_wire: The wire to clone
:param name: a name fo rhte new wire
Note that this function is mainly intended to be used when the
two wires are from different blocks. Making two wires with the
same name in the same block is not allowed
"""
if isinstance(old_wire, Const):
return Const(old_wire.val, old_wire.bitwidth)
else:
if name is None:
return old_wire.__class__(old_wire.bitwidth, name=old_wire.name)
return old_wire.__class__(old_wire.bitwidth, name=name)
def extract_cover(command):
netio = command['namesignal_list']
if len(command['cover_list']) == 0:
output_wire = twire(netio[0])
output_wire <<= Const(0, bitwidth=1, block=block) # const "FALSE"
elif command['cover_list'].asList() == ['1']:
output_wire = twire(netio[0])
output_wire <<= Const(1, bitwidth=1, block=block) # const "TRUE"
elif command['cover_list'].asList() == ['1', '1']:
# Populate clock list if one input is already a clock
if(netio[1] in clk_set):
clk_set.add(netio[0])
elif(netio[0] in clk_set):
clk_set.add(netio[1])
else:
output_wire = twire(netio[1])
output_wire <<= twire(netio[0]) # simple wire
elif command['cover_list'].asList() == ['0', '1']:
output_wire = twire(netio[1])
output_wire <<= ~ twire(netio[0]) # not gate
elif command['cover_list'].asList() == ['11', '1']:
output_wire = twire(netio[2])
output_wire <<= twire(netio[0]) & twire(netio[1]) # and gate
elif command['cover_list'].asList() == ['00', '1']:
def _const_to_int(wire, const_dict):
if isinstance(wire, Const):
# a very bad hack to make sure two consts will compare
# correctly with an 'is'
bitwidth = wire.bitwidth
val = wire.val
if bitwidth not in const_dict:
const_dict[bitwidth] = {val: (bitwidth, val)}
else:
if val not in const_dict[bitwidth]:
const_dict[bitwidth][val] = (bitwidth, val)
return const_dict[bitwidth][val]
return wire
def _finalize():
"""Build the required muxes and call back to WireVector to finalize the wirevector build."""
from .memory import MemBlock
from pyrtl.corecircuits import select
for lhs in _predicate_map:
# handle memory write ports
if isinstance(lhs, MemBlock):
p, (addr, data, enable) = _predicate_map[lhs][0]
combined_enable = select(p, truecase=enable, falsecase=Const(0))
combined_addr = addr
combined_data = data
for p, (addr, data, enable) in _predicate_map[lhs][1:]:
combined_enable = select(p, truecase=enable, falsecase=combined_enable)
combined_addr = select(p, truecase=addr, falsecase=combined_addr)
combined_data = select(p, truecase=data, falsecase=combined_data)
lhs._build(combined_addr, combined_data, combined_enable)
# handle wirevector and register assignments
else:
if isinstance(lhs, Register):
result = lhs # default for registers is "self"
elif isinstance(lhs, WireVector):
result = 0 # default for wire is "0"