Unable to display the simulation with EDAPlayground compiler - myhdl

I have tried the following code from myHDL manual on EDAPlayground.com, but it didn't print anything out for me. Can anyone show me why ? and how to solve this ?
My configuration on the site is outlined here.
Testbench+Design : Python only
Methodology : MyHDL 0.8
from random import randrange
from myhdl import *
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
def Inc(count, enable, clock, reset, n):
""" Incrementer with enable.
count -- output
enable -- control input, increment when 1
clock -- clock input
reset -- asynchronous reset input
n -- counter max value
"""
#always_seq(clock.posedge, reset=reset)
def incLogic():
if enable:
count.next = (count + 1) % n
return incLogic
def testbench():
count, enable, clock = [Signal(intbv(0)) for i in range(3)]
# Configure your reset signal here (active type, async/sync)
reset = ResetSignal(0,active=ACTIVE_LOW,async=True)
## DUT to be instantiated
inc_1 = Inc(count, enable, clock, reset, n=4)
HALF_PERIOD = delay(10)
## forever loop : clock generator
#always(HALF_PERIOD)
def clockGen():
clock.next = not clock
## Stimulus generator
#instance
def stimulus():
reset.next = ACTIVE_LOW
yield clock.negedge
reset.next = INACTIVE_HIGH
for i in range(12):
enable.next = min(1, randrange(3))
yield clock.negedge
raise StopSimulation
#instance
def monitor():
print "enable count"
yield reset.posedge
while 1:
yield clock.posedge
yield delay(1)
print " %s %s" % (enable, count)
return clockGen, stimulus, inc_1, monitor
tb = testbench()
def main():
Simulation(tb).run()

You need to call the main() function at the end.
E.g., add a line
main()
at the end, or better, use Python's idiom of
if __name__=="__main__":
main()

Related

How do I make Simpy simulation to depict a markovian M/M/1 process?

output printing the len of arrival and service timesI am trying to implement an M/M/1 markovian process with exponential inter arrival and exponential service times using simpy. The code runs fine but I dont quite get the expected results. Also the number of list items in arrival times is lesser than the number of list items in service time after the code is run.
# make a markovian queue
# make a server as a resource
# make customers at random times
# record the customer arrival time
# customer gets the resource
# record when the customer got the resource
# serve the customers for a random time using resource
# save this random time as service time
# customer yields the resource and next is served
import statistics
import simpy
import random
arrival_time = []
service_time = []
mean_service = 2.0
mean_arrival = 1.0
num_servers = 1
class Markovian(object):
def __init__(self, env, num_servers):
self.env = env
self.servers = simpy.Resource(env, num_servers)
#self.action = env.process(self.run())
def server(self,packet ):
#timeout after random service time
t = random.expovariate(1.0/mean_service)
#service_time.append(t)
yield self.env.timeout(t)
def getting_service(env, packet, markovian):
# new packet arrives in the system
arrival_time = env.now
with markovian.servers.request() as req:
yield req
yield env.process(markovian.server(packet))
service_time.append(env.now - arrival_time)
def run_markovian(env,num_servers):
markovian = Markovian(env,num_servers)
packet = 0
#generate new packets
while True:
t = random.expovariate(1.0/mean_arrival)
arrival_time.append(t)
yield env.timeout(t)
packet +=1
env.process(Markovian.getting_service(env,packet,markovian))
def get_average_service_time(service_time):
average_service_time = statistics.mean(service_time)
return average_service_time
def main():
random.seed(42)
env= simpy.Environment()
env.process(Markovian.run_markovian(env,num_servers))
env.run(until = 50)
print(Markovian.get_average_service_time(service_time))
print (arrival_time)
print (service_time)
if __name__ == "__main__":
main()
Hello there were basically one bug in your code and two queuing theory misconceptions:
Bug 1) the definition of the servers were inside the class, this makes the model behaves as a M/M/inf not M/M/1
Answer: I put the definition of your resources out the the class, and pass the servers not the num_servers from now on.
Misconception 1: with the times as you defined:
mean_service = 2.0
mean_arrival = 1.0
The system will generate much more packets and it is able to serve. That's why the size of the lists were so different.
Answer:
mean_service = 1.0
mean_arrival = 2.0
Misconception 2:
What you call service time in your code is actually system time.
I also put some prints in your code so we could see that is doing. Fell free to comment them. And there is no need for the library Statistics, so I commented it too.
I hope this answer is useful to you.
# make a markovian queue
# make a server as a resource
# make customers at random times
# record the customer arrival time
# customer gets the resource
# record when the customer got the resource
# serve the customers for a random time using resource
# save this random time as service time
# customer yields the resource and next is served
#import statistics
import simpy
import random
arrivals_time = []
service_time = []
waiting_time = []
mean_service = 1.0
mean_arrival = 2.0
num_servers = 1
class Markovian(object):
def __init__(self, env, servers):
self.env = env
#self.action = env.process(self.run())
#def server(self,packet ):
#timeout after random service time
# t = random.expovariate(1.0/mean_service)
#service_time.append(t)
# yield self.env.timeout(t)
def getting_service(env, packet, servers):
# new packet arrives in the system
begin_wait = env.now
req = servers.request()
yield req
begin_service = env.now
waiting_time.append(begin_service - begin_wait)
print('%.1f Begin Service of packet %d' % (begin_service, packet))
yield env.timeout(random.expovariate(1.0/mean_service))
service_time.append(env.now - begin_service)
yield servers.release(req)
print('%.1f End Service of packet %d' % (env.now, packet))
def run_markovian(env,servers):
markovian = Markovian(env,servers)
packet = 0
#generate new packets
while True:
t = random.expovariate(1.0/mean_arrival)
yield env.timeout(t)
arrivals_time.append(t)
packet +=1
print('%.1f Arrival of packet %d' % (env.now, packet))
env.process(Markovian.getting_service(env,packet,servers))
def get_average_service_time(service_time):
average_service_time = statistics.mean(service_time)
return average_service_time
def main():
random.seed(42)
env= simpy.Environment()
servers = simpy.Resource(env, num_servers)
env.process(Markovian.run_markovian(env,servers))
env.run(until = 50)
print(Markovian.get_average_service_time(service_time))
print ("Time between consecutive arrivals \n", arrivals_time)
print("Size: ", len(arrivals_time))
print ("Service Times \n", service_time)
print("Size: ", len(service_time))
print ("Waiting Times \n", service_time)
print (waiting_time)
print("Size: ",len(waiting_time))
if __name__ == "__main__":
main()

Analog control Raspberry pi using pyPS4Controller

I have a Raspberry Pi with a robotic kit and I would like to control it using a PS4 controller but using analog input. I have successfully connected the controller and I can read events and program the motors to answer binary input. The documentation (pyPS4Controller), however, is not explicit about using analog values (Ex: 50% press on R2 outputs 0.5 forward).
Could someone please help me figure out how to make this?
Thanks in advance!
# This is the example for binary buttons
from pyPS4Controller.controller import Controller
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
def on_x_press(self):
print("Forward")
def on_x_release(self):
print("Stop")
# --> The objective is having some way to capture the "intensity" of the button press to use the motors accordingly
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
controller.listen()
After some tweaking and trial and error I ended up finding a solution.
The analog functions receive an input called value containing the analog value of the input given to the controller.
from pyPS4Controller.controller import Controller
from gpiozero import CamJamKitRobot as camjam
# Translate controller input into motor output values
def transf(raw):
temp = (raw+32767)/65534
# Filter values that are too weak for the motors to move
if abs(temp) < 0.25:
return 0
# Return a value between 0.3 and 1.0
else:
return round(temp, 1)
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
self.robot = camjam()
def on_R2_press(self, value):
# 'value' becomes 0 or a float between 0.3 and 1.0
value = transf(value)
self.robot.value = (value, value)
print(f"R2 {value}")
def on_R2_release(self):
self.robot.value = (0,0)
print(f"R2 FREE")
def on_L2_press(self, value):
# 'value' becomes 0 or a float between -1.0 and -0.3
value = -transf(value)
self.robot.value = (value, value)
print(f"L2 {value}")
def on_L2_release(self):
self.robot.value = (0,0)
print(f"L2 FREE")
# Press OPTIONS (=START) to stop and exit
def on_options_press(self):
print("\nExiting (START)")
self.robot.value = (0,0)
exit(1)
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
controller.listen()

Storage values using os.stat(filename)

I'm trying to create an EDUCATIONAL PURPOSES ONLY virus. I do not plan on spreading it. It's purpose is to grow a file to the point your storage is full and slow your computer down. It prints the size of the file every 0.001 seconds. With that, I also want to know how fast it is growing the file. The following code doesn't seem to let it run:
class Vstatus():
def _init_(Status):
Status.countspeed == True
Status.active == True
Status.growingspeed == 0
import time
import os
#Your storage is at risk of over-expansion. Please do not let this file run forever, as your storage will fill continuously.
#This is for educational purposes only.
while Vstatus.Status.countspeed == True:
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
Key1 = fsize
time.sleep(1)
Key2 = fsize
Vstatus.Status.growingspeed = (Key2 - Key1)
Vstatus.Status.countspeed = False
while Vstatus.Status.active == True:
time.sleep(0.001)
f = open('file.txt', 'a')
f.write('W')
fsize = os.stat('file.txt')
print('size:' + fsize.st_size.__str__() + ' at a speed of ' + Vstatus.Status.growingspeed + 'bytes per second.')
This is for Educational Purposes ONLY
The main error I keep getting when running the file is here:
TypeError: unsupported operand type(s) for -: 'os.stat_result' and 'os.stat_result'
What does this mean? I thought os.stat returned an integer Can I get a fix on this?
Vstatus.Status.growingspeed = (Key2 - Key1)
You can't subtract os.stat objects. Your code also has some other problems. Your loops will run sequentially, meaning that your first loop will try to estimate how quickly the file is being written to without writing anything to the file.
import time # Imports at the top
import os
class VStatus:
def __init__(self): # double underscores around __init__
self.countspeed = True # Assignment, not equality test
self.active = True
self.growingspeed = 0
status = VStatus() # Make a VStatus instance
# You need to do the speed estimation and file appending in the same loop
with open('file.txt', 'a+') as f: # Only open the file once
start = time.time() # Get the current time
starting_size = os.fstat(f.fileno()).st_size
while status.active: # Access the attribute of the VStatus instance
size = os.fstat(f.fileno()).st_size # Send file desciptor to stat
f.write('W') # Writing more than one character at a time will be your biggest speed up
f.flush() # make sure the byte is written
if status.countspeed:
diff = time.time() - start
if diff >= 1: # More than a second has gone by
status.countspeed = False
status.growingspeed = (os.fstat(f.fileno()).st_size - starting_size)/diff # get rate of growth
else:
print(f"size: {size} at a speed of {status.growingspeed}")

Simpy: How can I represent failures in a train subway simulation?

New python user here and first post on this great website. I haven't been able to find an answer to my question so hopefully it is unique.
Using simpy I am trying to create a train subway/metro simulation with failures and repairs periodically built into the system. These failures happen to the train but also to signals on sections of track and on plaforms. I have read and applied the official Machine Shop example (which you can see resemblance of in the attached code) and have thus managed to model random failures and repairs to the train by interrupting its 'journey time'.
However I have not figured out how to model failures of signals on the routes which the trains follow. I am currently just specifying a time for a trip from A to B, which does get interrupted but only due to train failure.
Is it possible to define each trip as its own process i.e. a separate process for sections A_to_B and B_to_C, and separate platforms as pA, pB and pC. Each one with a single resource (to allow only one train on it at a time) and to incorporate random failures and repairs for these section and platform processes? I would also need to perhaps have several sections between two platforms, any of which could experience a failure.
Any help would be greatly appreciated.
Here's my code so far:
import random
import simpy
import numpy
RANDOM_SEED = 1234
T_MEAN_A = 240.0 # mean journey time
T_MEAN_EXPO_A = 1/T_MEAN_A # for exponential distribution
T_MEAN_B = 240.0 # mean journey time
T_MEAN_EXPO_B = 1/T_MEAN_B # for exponential distribution
DWELL_TIME = 30.0 # amount of time train sits at platform for passengers
DWELL_TIME_EXPO = 1/DWELL_TIME
MTTF = 3600.0 # mean time to failure (seconds)
TTF_MEAN = 1/MTTF # for exponential distribution
REPAIR_TIME = 240.0
REPAIR_TIME_EXPO = 1/REPAIR_TIME
NUM_TRAINS = 1
SIM_TIME_DAYS = 100
SIM_TIME = 3600 * 18 * SIM_TIME_DAYS
SIM_TIME_HOURS = SIM_TIME/3600
# Defining the times for processes
def A_B(): # returns processing time for journey A to B
return random.expovariate(T_MEAN_EXPO_A) + random.expovariate(DWELL_TIME_EXPO)
def B_C(): # returns processing time for journey B to C
return random.expovariate(T_MEAN_EXPO_B) + random.expovariate(DWELL_TIME_EXPO)
def time_to_failure(): # returns time until next failure
return random.expovariate(TTF_MEAN)
# Defining the train
class Train(object):
def __init__(self, env, name, repair):
self.env = env
self.name = name
self.trips_complete = 0
self.broken = False
# Start "travelling" and "break_train" processes for the train
self.process = env.process(self.running(repair))
env.process(self.break_train())
def running(self, repair):
while True:
# start trip A_B
done_in = A_B()
while done_in:
try:
# going on the trip
start = self.env.now
yield self.env.timeout(done_in)
done_in = 0 # Set to 0 to exit while loop
except simpy.Interrupt:
self.broken = True
done_in -= self.env.now - start # How much time left?
with repair.request(priority = 1) as req:
yield req
yield self.env.timeout(random.expovariate(REPAIR_TIME_EXPO))
self.broken = False
# Trip is finished
self.trips_complete += 1
# start trip B_C
done_in = B_C()
while done_in:
try:
# going on the trip
start = self.env.now
yield self.env.timeout(done_in)
done_in = 0 # Set to 0 to exit while loop
except simpy.Interrupt:
self.broken = True
done_in -= self.env.now - start # How much time left?
with repair.request(priority = 1) as req:
yield req
yield self.env.timeout(random.expovariate(REPAIR_TIME_EXPO))
self.broken = False
# Trip is finished
self.trips_complete += 1
# Defining the failure
def break_train(self):
while True:
yield self.env.timeout(time_to_failure())
if not self.broken:
# Only break the train if it is currently working
self.process.interrupt()
# Setup and start the simulation
print('Train trip simulator')
random.seed(RANDOM_SEED) # Helps with reproduction
# Create an environment and start setup process
env = simpy.Environment()
repair = simpy.PreemptiveResource(env, capacity = 1)
trains = [Train(env, 'Train %d' % i, repair)
for i in range(NUM_TRAINS)]
# Execute
env.run(until = SIM_TIME)
# Analysis
trips = []
print('Train trips after %s hours of simulation' % SIM_TIME_HOURS)
for train in trains:
print('%s completed %d trips.' % (train.name, train.trips_complete))
trips.append(train.trips_complete)
mean_trips = numpy.mean(trips)
std_trips = numpy.std(trips)
print "mean trips: %d" % mean_trips
print "standard deviation trips: %d" % std_trips
it looks like you are using Python 2, which is a bit unfortunate, because
Python 3.3 and above give you some more flexibility with Python generators. But
your problem should be solveable in Python 2 nonetheless.
you can use sub processes within in a process:
def sub(env):
print('I am a sub process')
yield env.timeout(1)
# return 23 # Only works in py3.3 and above
env.exit(23) # Workaround for older python versions
def main(env):
print('I am the main process')
retval = yield env.process(sub(env))
print('Sub returned', retval)
As you can see, you can use Process instances returned by Environment.process()
like normal events. You can even use return values in your sub proceses.
If you use Python 3.3 or newer, you don’t have to explicitly start a new
sub-process but can use sub() as a sub routine instead and just forward the
events it yields:
def sub(env):
print('I am a sub routine')
yield env.timeout(1)
return 23
def main(env):
print('I am the main process')
retval = yield from sub(env)
print('Sub returned', retval)
You may also be able to model signals as resources that may either be used
by failure process or by a train. If the failure process requests the signal
at first, the train has to wait in front of the signal until the failure
process releases the signal resource. If the train is aleady passing the
signal (and thus has the resource), the signal cannot break. I don’t think
that’s a problem be cause the train can’t stop anyway. If it should be
a problem, just use a PreemptiveResource.
I hope this helps. Please feel welcome to join our mailing list for more
discussions.

Simpy subway simulation: how to fix interrupt failure of class train while queueing for a resource?

I am working on a train simulation in simpy and have had success so far with a single train entity following the code below.
The trains processes are sections followed by platforms. Each section and platform has a resource of 1 to ensure that only one train utilises at a time.
However I can't find a way to get around the error below:
When I add in a second train to the simulation there is occasionally the situation where one train waits for an unavailable resource and then a failure occurs on that train while it is waiting.
I end up with an Interrupt: Interrupt() error.
Is there a way around these failing queues for resources?
Any help is much appreciated.
import random
import simpy
import numpy
# Configure parameters for the model
RANDOM_SEED = random.seed() # makes results repeatable
T_MEAN_SECTION = 200.0 # journey time (seconds)
DWELL_TIME = 30.0 # dwell time mean (seconds)
DWELL_TIME_EXPO = 1/DWELL_TIME # for exponential distribution
MTTF = 600.0 # mean time to failure (seconds)
TTF_MEAN = 1/MTTF # for exponential distribution
REPAIR_TIME = 120.0 # mean repair time for when failure occurs (seconds)
REPAIR_TIME_EXPO = 1/REPAIR_TIME # for exponential distribution
NUM_TRAINS = 2 # number of trains to simulate
SIM_TIME_HOURS = 1 # sim time in hours
SIM_TIME_DAYS = SIM_TIME_HOURS/18.0 # number of days to simulate
SIM_TIME = 3600 * 18 * SIM_TIME_DAYS # sim time in seconds (this is used in the code below)
# Defining the times for processes
def Section(): # returns processing time for platform 7 Waterloo to 26 Bank
return T_MEAN_SECTION
def Dwell(): # returns processing time for platform 25 Bank to platform 7 Waterloo
return random.expovariate(DWELL_TIME_EXPO)
def time_to_failure(): # returns time until next failure
return random.expovariate(TTF_MEAN)
# Defining the train
class Train(object):
def __init__(self, env, name, repair):
self.env = env
self.name = name
self.trips_complete = 0
self.num_saf = 0
self.sum_saf = 0
self.broken = False
# Start "running" and "downtime_train" processes for the train
self.process = env.process(self.running(repair))
env.process(self.downtime_train())
def running(self, repair):
while True:
# request section A
request_SA = sectionA.request()
########## SIM ERROR IF FAILURE OCCURS HERE ###########
yield request_SA
done_in_SA = Section()
while done_in_SA:
try:
# going on the trip
start = self.env.now
print('%s leaving platform at time %d') % (self.name, env.now)
# processing time
yield self.env.timeout(done_in_SA)
# releasing the section resource
sectionA.release(request_SA)
done_in_SA = 0 # Set to 0 to exit while loop
except simpy.Interrupt:
self.broken = True
delay = random.expovariate(REPAIR_TIME_EXPO)
print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now)
done_in_SA -= self.env.now - start # How much time left?
with repair.request(priority = 1) as request_D_SA:
yield request_D_SA
yield self.env.timeout(delay)
self.broken = False
print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now)
self.num_saf += 1
self.sum_saf += delay
# request platform A
request_PA = platformA.request()
########## SIM ERROR IF FAILURE OCCURS HERE ###########
yield request_PA
done_in_PA = Dwell()
while done_in_PA:
try:
# platform process
start = self.env.now
print('%s arriving to platform A and opening doors at time %d') % (self.name, env.now)
yield self.env.timeout(done_in_PA)
print('%s closing doors, ready to depart platform A at %d\n') % (self.name, env.now)
# releasing the platform resource
platformA.release(request_PA)
done_in_PA = 0 # Set to 0 to exit while loop
except simpy.Interrupt:
self.broken = True
delay = random.expovariate(REPAIR_TIME_EXPO)
print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now)
done_in_PA -= self.env.now - start # How much time left?
with repair.request(priority = 1) as request_D_PA:
yield request_D_PA
yield self.env.timeout(delay)
self.broken = False
print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now)
self.num_saf += 1
self.sum_saf += delay
# Round trip is finished
self.trips_complete += 1
# Defining the failure event
def downtime_train(self):
while True:
yield self.env.timeout(time_to_failure())
if not self.broken:
# Only break the train if it is currently working
self.process.interrupt()
# Setup and start the simulation
print('Train trip simulator')
random.seed(RANDOM_SEED) # Helps with reproduction
# Create an environment and start setup process
env = simpy.Environment()
# Defining resources
platformA = simpy.Resource(env, capacity = 1)
sectionA = simpy.Resource(env, capacity = 1)
repair = simpy.PreemptiveResource(env, capacity = 10)
trains = [Train(env, 'Train %d' % i, repair)
for i in range(NUM_TRAINS)]
# Execute
env.run(until = SIM_TIME)
Your processes request a resource and never release it. That’s why the second trains waits forever for its request to succeed. While it is waiting, the failure process seems to interrupt the process. That’s why you get an error. Please read the guide to resources to understand how SimPy’s resources work and, especially, how to release a resource when you are done.