Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_mem_val_map(self):
read_addr3 = pyrtl.Input(self.addrwidth)
self.output3 = pyrtl.Output(self.bitwidth, "o3")
self.output3 <<= self.mem2[read_addr3]
mem_val_map = {self.mem1: {0: 0, 1: 1, 2: 2, 3: 3},
self.mem2: {0: 4, 1: 5, 2: 6, 3: 7}}
self.sim_trace = pyrtl.SimulationTrace()
sim = self.sim(tracer=self.sim_trace, memory_value_map=mem_val_map)
# put new entries in
for i in range(2):
sim.step({
self.read_addr1: 4 + i, # d.c.
self.read_addr2: 4 + i, # d.c.
read_addr3: 2,
self.write_addr: 4 + i, # put a 4 and a 5 in the 4th and 5th addr of mem1
self.write_data: 4 + i
})
# modify existing entries
for i in range(2):
def setUp(self):
pyrtl.reset_working_block()
self.bitwidth = 3
self.addrwidth = 5
self.output1 = pyrtl.Output(self.bitwidth, "output1")
self.output2 = pyrtl.Output(self.bitwidth, "output2")
self.mem_read_address1 = pyrtl.Input(self.addrwidth, name='mem_read_address1')
self.mem_read_address2 = pyrtl.Input(self.addrwidth, name='mem_read_address2')
self.mem_write_address = pyrtl.Input(self.addrwidth, name='mem_write_address')
self.mem_write_data = pyrtl.Input(self.bitwidth, name='mem_write_data')
self.memory = pyrtl.MemBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth,
name='self.memory')
def setUp(self):
pyrtl.reset_working_block()
self.bitwidth = 3
self.addrwidth = 4
self.output1 = pyrtl.Output(self.bitwidth, "o1")
self.output2 = pyrtl.Output(self.bitwidth, "o2")
self.read_addr1 = pyrtl.Input(self.addrwidth)
self.read_addr2 = pyrtl.Input(self.addrwidth)
self.write_addr = pyrtl.Input(self.addrwidth)
self.write_data = pyrtl.Input(self.bitwidth)
self.rom = pyrtl.MemBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth,
name='rom')
self.output1 <<= self.rom[self.read_addr1]
self.output2 <<= self.rom[self.read_addr2]
self.rom[self.write_addr] <<= self.write_data
# build the actual simulation environment
self.sim_trace = pyrtl.SimulationTrace()
def test_function_RomBlock_with_optimization(self):
def rom_data_function(add):
return int((add + 5)/2)
pyrtl.reset_working_block()
self.bitwidth = 4
self.addrwidth = 4
self.output1 = pyrtl.Output(self.bitwidth, "o1")
self.output2 = pyrtl.Output(self.bitwidth, "o2")
self.read_addr1 = pyrtl.Input(self.addrwidth)
self.read_addr2 = pyrtl.Input(self.addrwidth)
self.rom = pyrtl.RomBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth,
name='rom', romdata=rom_data_function)
self.output1 <<= self.rom[self.read_addr1]
self.output2 <<= self.rom[self.read_addr2]
pyrtl.synthesize()
pyrtl.optimize()
# build the actual simulation environment
self.sim_trace = pyrtl.SimulationTrace()
self.sim = self.sim(tracer=self.sim_trace)
input_signals = {}
for i in range(0, 5):
# --- Step 1: Define Logic -------------------------------------------------
# One of the most fundamental types in PyRTL is the "WireVector" which is acts
# very much like a python list of 1-bit wires. Unlike a normal list though the
# number of bits is explicitly declared.
temp1 = pyrtl.WireVector(bitwidth=1, name='temp1')
# Both arguments are in fact optional and default to a bitwidth of 1 and a unique
# name generated by pyrtl starting with 'tmp'
temp2 = pyrtl.WireVector()
# Two special types of WireVectors are Input and Output, which are used to specify
# an interface to the hardware block.
a, b, c = pyrtl.Input(1, 'a'), pyrtl.Input(1, 'b'), pyrtl.Input(1, 'c')
sum, carry_out = pyrtl.Output(1, 'sum'), pyrtl.Output(1, 'carry_out')
# Okay, let's build a one-bit adder. To do this we need to use the assignment
# operator, which is '<<='. This takes an already declared wire and "connects"
# it to some other already declared wire. Let's start with the sum bit, which is
# of course just the xor of the three inputs
sum <<= a ^ b ^ c
# The carry_out bit would just be "carry_out <<= a & b | a & c | b & c" but let's break
# than down a bit to see what is really happening. What if we want to give names
# to the partial signals in the middle of that computation. When you take
# "a & b" in PyRTL what that really means is "make an AND gate, connect one input
# to 'a' and the other to 'b' and return the result of the gate". The result of
# that AND gate can then be assigned to temp1 or it can be used like any other
# python variable.
temp1 <<= a & b # connect the result of a & b to the pre-allocated wirevector
def test_memblock_assign_with_extention(self):
big_output = pyrtl.Output(self.bitwidth+1, "big_output")
big_output <<= self.memory[self.mem_read_address1]
self.output1 <<= 1
self.output2 <<= 2
self.memory[self.mem_write_address] <<= self.mem_write_data
pyrtl.working_block().sanity_check()
def testBasicGates():
a, b = Input(1, 'a'), Input(1, 'b')
z1, z2, z3 = Output(1, 'z1'), Output(1, 'z2'), Output(1, 'z3')
z1 <<= a & b
z2 <<= a | b
z3 <<= a ^ b
a.tainted = True
dists = [(.75,0.), (.75,.5), (.75,1.)]
for dist in dists:
a.DIST0 = dist[0]
a.DIST1 = 1.0 - dist[0]
b.DIST0 = dist[1]
b.DIST1 = 1.0 - dist[1]
mibound(pyrtl.working_block())
def test_buffer():
buffer_addrwidth = 2
buffer_bitwidth = 8
write_enable = pyrtl.Input(1,'write_enable')
read_enable = pyrtl.Input(1,'read_enable')
data_in = pyrtl.Input(buffer_bitwidth,'data_in')
data_out = pyrtl.Output(buffer_bitwidth,'data_out')
valid = pyrtl.Output(1,'valid')
full = pyrtl.Output(1,'full')
read_output, valid_output, full_output = surfnoc_buffer(buffer_bitwidth, buffer_addrwidth, data_in, write_enable, read_enable)
data_out <<= read_output
valid <<= valid_output
full <<= full_output
simvals = {
write_enable: "111111110000111100000001111",
data_in: "123456780000678900000001234",
read_enable: "000000001111000001111111111"
}
sim_trace=pyrtl.SimulationTrace()
sim=pyrtl.Simulation(tracer=sim_trace)
for cycle in range(len(simvals[write_enable])):
sim.step({k: int(v[cycle]) for k,v in simvals.items()})
"""
import sys
sys.path.append('/home/abe/school/PyRTL')
import pyrtl
# Newly created wires are associated with the default clock domain
i1 = pyrtl.Input(name='i1', bitwidth=3)
print(i1.clock) # Clock('clk')
# New clocks can be created
fast = pyrtl.Clock('fast')
# The clock for a wire can be specified
i2 = pyrtl.Input(name='i2', bitwidth=3, clock=fast)
# If several wires will use the same clock, it can be set as the new default
fast.set_default()
o1 = pyrtl.Output(name='o1', bitwidth=3)
print(o1.clock) # Clock('fast')
# The original default clock is accessible through the block
clk = pyrtl.working_block().clocks['clk']
clk.set_default()
o2 = pyrtl.Output(name='o2', bitwidth=3)
# To automatically change the default clock back, a context manager can be used:
with fast.set_default():
# Anything created in this block uses Clock('fast')
i3 = pyrtl.Input(name='i3', bitwidth=3)
r1 = pyrtl.Register(name='r1', bitwidth=3)
# And now it returns to Clock('clk')
r2 = pyrtl.Register(name='r2', bitwidth=3)
# The default clock doesn't matter when building logic
r1.next <<= i2 + i3
o1 <<= r1
r2.next <<= i1
def testadder():
a,b,c = Input(1,'a'), Input(1,'b'), Input(1,'c')
sum, cout = Output(1,'sum'), Output(1,'cout')
sum <<= a ^ b ^ c
cout <<= a & b | a & c | b & c
a.DIST0, a.DIST1 = .15, .15
b.DIST0, b.DIST1 = .15, .15
c.DIST0, c.DIST1 = .15, .15
print mibound(pyrtl.working_block())
for i in range(10):
for x in (a,b,c):
x.DIST0 = np.random.rand()
x.DIST1 = np.random.rand()
print mibound(pyrtl.working_block())