host: split read/export and add csv export
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 17 Jun 2014 09:25:10 +0000 (11:25 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Tue, 17 Jun 2014 09:25:10 +0000 (11:25 +0200)
miscope/host/drivers.py
miscope/host/export.py [new file with mode: 0644]
miscope/host/vcd.py [deleted file]

index 7668af673dceed80d6965c08fe7d680d9f384ef4..423b7d393b305f86d586d45448e5f70a438b23d8 100644 (file)
@@ -1,7 +1,7 @@
 import csv
 import time
 import sys
-from miscope.host.vcd import *
+from miscope.host.export import *
 from miscope.host.truthtable import *
 
 class MiIoDriver():
@@ -23,20 +23,19 @@ 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":
@@ -44,7 +43,7 @@ class MiLaDriver():
 
        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":
@@ -64,10 +63,8 @@ class MiLaDriver():
                        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):
@@ -116,8 +113,8 @@ class MiLaDriver():
                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())
@@ -125,8 +122,17 @@ class MiLaDriver():
                        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
diff --git a/miscope/host/export.py b/miscope/host/export.py
new file mode 100644 (file)
index 0000000..d9b8050
--- /dev/null
@@ -0,0 +1,313 @@
+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()
+
diff --git a/miscope/host/vcd.py b/miscope/host/vcd.py
deleted file mode 100644 (file)
index 0259e60..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-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()
-