import csv
import time
import sys
-from miscope.host.vcd import *
+from miscope.host.export import *
from miscope.host.truthtable import *
class MiIoDriver():
return self.miio_i.read()
class MiLaDriver():
- def __init__(self, regs, name, csv_name=None, use_rle=True):
+ def __init__(self, regs, name, config_csv=None, use_rle=True):
self.regs = regs
self.name = name
self.use_rle = use_rle
-
- if csv_name is None:
- self.csv = name + ".csv"
+ if config_csv is None:
+ self.config_csv = name + ".csv"
self.get_config()
self.get_layout()
self.build_mila()
- self.dat = VcdDat(self.width)
+ self.dat = Dat(self.width)
def get_config(self):
- csv_reader = csv.reader(open(self.csv), delimiter=',', quotechar='#')
+ csv_reader = csv.reader(open(self.config_csv), delimiter=',', quotechar='#')
for item in csv_reader:
t, n, v = item
if t == "config":
def get_layout(self):
self.layout = []
- csv_reader = csv.reader(open(self.csv), delimiter=',', quotechar='#')
+ csv_reader = csv.reader(open(self.config_csv), delimiter=',', quotechar='#')
for item in csv_reader:
t, n, v = item
if t == "layout":
setattr(self, name+"_m", (2**length-1) << value)
value += length
- def show_state(self, s, last=False):
- print(s, end="")
- if not last:
- print("-->", end="")
+ def show_state(self, s):
+ print(s, end="|")
sys.stdout.flush()
def prog_term(self, port, trigger, mask):
self.mila_recorder_length.write(length)
self.mila_recorder_trigger.write(1)
- def read(self, vcd=None):
- self.show_state("READ", last=not vcd)
+ def read(self):
+ self.show_state("READ")
empty = self.mila_recorder_read_empty.read()
while(not empty):
self.dat.append(self.mila_recorder_read_dat.read())
self.mila_recorder_read_en.write(1)
if self.use_rle:
self.dat = self.dat.decode_rle()
- if vcd:
- self.show_state("OUTPUT", last=True)
- _vcd = Vcd()
- _vcd.add_from_layout(self.layout, self.dat)
- _vcd.write(vcd)
+ return self.dat
+
+ def export(self, export_fn=None):
+ self.show_state("EXPORT")
+ if ".vcd" in export_fn:
+ vcd = VCD()
+ vcd.add_from_layout(self.layout, self.dat)
+ vcd.write(export_fn)
+ elif ".csv" in export_fn:
+ csv = CSV()
+ csv.add_from_layout(self.layout, self.dat)
+ csv.write(export_fn)
+ else:
+ raise NotImplementedError
--- /dev/null
+import sys
+import datetime
+
+def dec2bin(d, nb=0):
+ if d=="x":
+ return "x"*nb
+ elif d==0:
+ b="0"
+ else:
+ b=""
+ while d!=0:
+ b="01"[d&1]+b
+ d=d>>1
+ return b.zfill(nb)
+
+def get_bits(values, width, low, high=None):
+ r = []
+ for val in values:
+ t = dec2bin(val, width)[::-1]
+ if high == None:
+ t = t[low]
+ else:
+ t = t[low:high]
+ t = t[::1]
+ t = int(t,2)
+ r.append(t)
+ return r
+
+class Dat(list):
+ def __init__(self, width):
+ self.width = width
+
+ def __getitem__(self, key):
+ if isinstance(key, int):
+ return get_bits(self, self.width, key)
+ elif isinstance(key, slice):
+ if key.start != None:
+ start = key.start
+ else:
+ start = 0
+ if key.stop != None:
+ stop = key.stop
+ else:
+ stop = self.width
+ if stop > self.width:
+ stop = self.width
+ if key.step != None:
+ raise KeyError
+ return get_bits(self, self.width, start, stop)
+ else:
+ raise KeyError
+
+ def decode_rle(self):
+ rle_bit = self[-1]
+ rle_dat = self[:self.width-1]
+
+ dat = Dat(self.width)
+ i=0
+ last = 0
+ for d in self:
+ if rle_bit[i]:
+ if len(dat) >= 1:
+ # FIX ME... why is rle_dat in reverse order...
+ for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
+ dat.append(last)
+ else:
+ dat.append(d)
+ last = d
+ i +=1
+ return dat
+
+class Var:
+ def __init__(self, name, width, values=[], type="wire", default="x"):
+ self.type = type
+ self.width = width
+ self.name = name
+ self.val = default
+ self.values = values
+ self.vcd_id = None
+
+ def set_vcd_id(self, s):
+ self.vcd_id = s
+
+ def __len__(self):
+ return len(self.values)
+
+ def change(self, cnt):
+ r = ""
+ try :
+ if self.values[cnt+1] != self.val:
+ r += "b"
+ r += dec2bin(self.values[cnt+1], self.width)[::-1]
+ r += " "
+ r += self.vcd_id
+ r += "\n"
+ return r
+ except :
+ return r
+ return r
+
+class VCD:
+ def __init__(self, timescale="1ps", comment=""):
+ self.timescale = timescale
+ self.comment = comment
+ self.vars = []
+ self.vcd_id = "!"
+ self.cnt = -1
+
+ def add(self, var):
+ var.set_vcd_id(self.vcd_id)
+ self.vcd_id = chr(ord(self.vcd_id)+1)
+ self.vars.append(var)
+
+ def add_from_layout(self, layout, var):
+ i=0
+ for s, n in layout:
+ self.add(Var(s, n, var[i:i+n]))
+ i += n
+
+ def __len__(self):
+ l = 0
+ for var in self.vars:
+ l = max(len(var),l)
+ return l
+
+ def change(self):
+ r = ""
+ c = ""
+ for var in self.vars:
+ c += var.change(self.cnt)
+ if c != "":
+ r += "#"
+ r += str(self.cnt+1)
+ r += "\n"
+ r += c
+ return r
+
+ def p_date(self):
+ now = datetime.datetime.now()
+ r = "$date\n"
+ r += "\t"
+ r += now.strftime("%Y-%m-%d %H:%M")
+ r += "\n"
+ r += "$end\n"
+ return r
+
+ def p_version(self):
+ r = "$version\n"
+ r += "\tmiscope VCD dump\n"
+ r += "$end\n"
+ return r
+
+ def p_comment(self):
+ r = "$comment\n"
+ r += self.comment
+ r += "\n$end\n"
+ return r
+
+ def p_timescale(self):
+ r = "$timescale "
+ r += self.timescale
+ r += " $end\n"
+ return r
+
+ def p_scope(self):
+ r = "$scope "
+ r += self.timescale
+ r += " $end\n"
+ return r
+
+ def p_vars(self):
+ r = ""
+ for var in self.vars:
+ r += "$var "
+ r += var.type
+ r += " "
+ r += str(var.width)
+ r += " "
+ r += var.vcd_id
+ r += " "
+ r += var.name
+ r += " $end\n"
+ return r
+
+ def p_unscope(self):
+ r = "$unscope "
+ r += " $end\n"
+ return r
+
+ def p_enddefinitions(self):
+ r = "$enddefinitions "
+ r += " $end\n"
+ return r
+
+ def p_dumpvars(self):
+ r = "$dumpvars\n"
+ for var in self.vars:
+ r += "b"
+ r += dec2bin(var.val, var.width)
+ r += " "
+ r += var.vcd_id
+ r+= "\n"
+ r += "$end\n"
+ return r
+
+ def p_valuechange(self):
+ r = ""
+ for i in range(len(self)):
+ r += self.change()
+ self.cnt += 1
+ return r
+
+ def __repr__(self):
+ r = ""
+ r += self.p_date()
+ r += self.p_version()
+ r += self.p_comment()
+ r += self.p_timescale()
+ r += self.p_scope()
+ r += self.p_vars()
+ r += self.p_unscope()
+ r += self.p_enddefinitions()
+ r += self.p_dumpvars()
+ r += self.p_valuechange()
+ return r
+
+ def write(self, filename):
+ f = open(filename, "w")
+ f.write(str(self))
+ f.close()
+
+class CSV:
+ def __init__(self):
+ self.vars = []
+ self.cnt = -1
+
+ def add(self, var):
+ self.vars.append(var)
+
+ def add_from_layout(self, layout, var):
+ i=0
+ for s, n in layout:
+ self.add(Var(s, n, var[i:i+n]))
+ i += n
+
+ def __len__(self):
+ l = 0
+ for var in self.vars:
+ l = max(len(var),l)
+ return l
+
+ def p_vars(self):
+ r = ""
+ for var in self.vars:
+ r += var.name
+ r += ","
+ r += "\n"
+ for var in self.vars:
+ r += str(var.width)
+ r += ","
+ r += "\n"
+ return r
+
+ def p_dumpvars(self):
+ r = ""
+ for i in range(len(self)):
+ for var in self.vars:
+ try:
+ var.val = var.values[i]
+ except:
+ pass
+ if var.val == "x":
+ r += "x"
+ else:
+ r += dec2bin(var.val, var.width)
+ r += ", "
+ r+= "\n"
+ return r
+
+ def __repr__(self):
+ r = ""
+ r += self.p_vars()
+ r += self.p_dumpvars()
+ return r
+
+ def write(self, filename):
+ f = open(filename, "w")
+ f.write(str(self))
+ f.close()
+
+def main():
+ myvcd = VCD()
+ myvcd.add(Var("foo1", 1, [0,1,0,1,0,1]))
+ myvcd.add(Var("foo2", 2, [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
+ myvcd.add(Var("foo3", 3))
+ myvcd.add(Var("foo4", 4))
+ ramp = [i%128 for i in range(1024)]
+ myvcd.add(Var("ramp", 16, ramp))
+ print(myvcd)
+
+ mycsv = CSV()
+ mycsv.add(Var("foo1", 1, [0,1,0,1,0,1]))
+ mycsv.add(Var("foo2", 2, [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
+ mycsv.add(Var("foo3", 3))
+ mycsv.add(Var("foo4", 4))
+ ramp = [i%128 for i in range(1024)]
+ mycsv.add(Var("ramp", 16, ramp))
+ print(mycsv)
+
+
+if __name__ == '__main__':
+ main()
+
+++ /dev/null
-import sys
-import datetime
-
-def dec2bin(d, nb=0):
- if d=="x":
- return "x"*nb
- elif d==0:
- b="0"
- else:
- b=""
- while d!=0:
- b="01"[d&1]+b
- d=d>>1
- return b.zfill(nb)
-
-def get_bits(values, width, low, high=None):
- r = []
- for val in values:
- t = dec2bin(val, width)[::-1]
- if high == None:
- t = t[low]
- else:
- t = t[low:high]
- t = t[::1]
- t = int(t,2)
- r.append(t)
- return r
-
-class VcdDat(list):
- def __init__(self, width):
- self.width = width
-
- def __getitem__(self, key):
- if isinstance(key, int):
- return get_bits(self, self.width, key)
- elif isinstance(key, slice):
- if key.start != None:
- start = key.start
- else:
- start = 0
- if key.stop != None:
- stop = key.stop
- else:
- stop = self.width
- if stop > self.width:
- stop = self.width
- if key.step != None:
- raise KeyError
- return get_bits(self, self.width, start, stop)
- else:
- raise KeyError
-
- def decode_rle(self):
- rle_bit = self[-1]
- rle_dat = self[:self.width-1]
-
- dat = VcdDat(self.width)
- i=0
- last = 0
- for d in self:
- if rle_bit[i]:
- if len(dat) >= 1:
- # FIX ME... why is rle_dat in reverse order...
- for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
- dat.append(last)
- else:
- dat.append(d)
- last = d
- i +=1
- return dat
-
-class Var:
- def __init__(self, name, width, values=[], type="wire", default="x"):
- self.type = type
- self.width = width
- self.name = name
- self.val = default
- self.values = values
- self.vcd_id = None
-
- def set_vcd_id(self, s):
- self.vcd_id = s
-
- def __len__(self):
- return len(self.values)
-
- def change(self, cnt):
- r = ""
- try :
- if self.values[cnt+1] != self.val:
- r += "b"
- r += dec2bin(self.values[cnt+1], self.width)[::-1]
- r += " "
- r += self.vcd_id
- r += "\n"
- return r
- except :
- return r
- return r
-
-class Vcd:
- def __init__(self, timescale="1ps", comment=""):
- self.timescale = timescale
- self.comment = comment
- self.vars = []
- self.vcd_id = "!"
- self.cnt = -1
-
- def add(self, var):
- var.set_vcd_id(self.vcd_id)
- self.vcd_id = chr(ord(self.vcd_id)+1)
- self.vars.append(var)
-
- def add_from_layout(self, layout, var):
- i=0
- for s, n in layout:
- self.add(Var(s, n, var[i:i+n]))
- i += n
-
- def __len__(self):
- l = 0
- for var in self.vars:
- l = max(len(var),l)
- return l
-
- def change(self):
- r = ""
- c = ""
- for var in self.vars:
- c += var.change(self.cnt)
- if c != "":
- r += "#"
- r += str(self.cnt+1)
- r += "\n"
- r += c
- return r
-
- def p_date(self):
- now = datetime.datetime.now()
- r = "$date\n"
- r += "\t"
- r += now.strftime("%Y-%m-%d %H:%M")
- r += "\n"
- r += "$end\n"
- return r
-
- def p_version(self):
- r = "$version\n"
- r += "\tmiscope VCD dump\n"
- r += "$end\n"
- return r
-
- def p_comment(self):
- r = "$comment\n"
- r += self.comment
- r += "\n$end\n"
- return r
-
- def p_timescale(self):
- r = "$timescale "
- r += self.timescale
- r += " $end\n"
- return r
-
- def p_scope(self):
- r = "$scope "
- r += self.timescale
- r += " $end\n"
- return r
-
- def p_vars(self):
- r = ""
- for var in self.vars:
- r += "$var "
- r += var.type
- r += " "
- r += str(var.width)
- r += " "
- r += var.vcd_id
- r += " "
- r += var.name
- r += " $end\n"
- return r
-
- def p_unscope(self):
- r = "$unscope "
- r += " $end\n"
- return r
-
- def p_enddefinitions(self):
- r = "$enddefinitions "
- r += " $end\n"
- return r
-
- def p_dumpvars(self):
- r = "$dumpvars\n"
- for var in self.vars:
- r += "b"
- r += dec2bin(var.val, var.width)
- r += " "
- r += var.vcd_id
- r+= "\n"
- r += "$end\n"
- return r
-
- def p_valuechange(self):
- r = ""
- for i in range(len(self)):
- r += self.change()
- self.cnt += 1
- return r
-
- def __repr__(self):
- r = ""
- r += self.p_date()
- r += self.p_version()
- r += self.p_comment()
- r += self.p_timescale()
- r += self.p_scope()
- r += self.p_vars()
- r += self.p_unscope()
- r += self.p_enddefinitions()
- r += self.p_dumpvars()
- r += self.p_valuechange()
- return r
-
- def write(self, filename):
- f = open(filename, "w")
- f.write(str(self))
- f.close()
-
-def main():
- myvcd = Vcd()
- myvcd.add(Var("foo1", 1, [0,1,0,1,0,1]))
- myvcd.add(Var("foo2", 2, [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
- myvcd.add(Var("foo3", 3))
- myvcd.add(Var("foo4", 4))
- ramp = [i%128 for i in range(1024)]
- myvcd.add(Var("ramp", 16, ramp))
- print(myvcd)
-
-if __name__ == '__main__':
- main()
-