<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

import cairocffi as cairo
from tools.options import Options
from colour import Color
from vhdl_objects.wire import Wire

#default_font = 'Aegyptus'
default_font = 'jura'

radius = 3
rank_separation = 15
rank_top_margin = 20
line_length = 35
inout_margin = 7

bbox_w_margin = 7
bbox_h_margin = 7

multi_wire_symbol_size = 6
line_width = 1.0

wire_name_margin = 8

clk_period = 10
clk_period_2 = clk_period/2

class TestBenchGenerator:

    def __init__(self, filename, entity):
        file = open(filename, "w")
        file.write("-- This testBench was generated by pyVhdl2Sch --\n")
        file.write("LIBRARY ieee;\n")
        file.write("USE ieee.std_logic_1164.ALL;\n")
        file.write("USE ieee.std_logic_unsigned.all;\n\n")
        file.write("\n")
        file.write("-- entity declaration\n")
        file.write("entity tb_%s IS\n" % entity.name)
        file.write("END tb_%s;\n\n" % entity.name)
        file.write("ARCHITECTURE behavior OF tb_%s IS\n" % entity.name)
        file.write("-- Component Declaration for the Unit Under Test (UUT)\n")
        file.write("COMPONENT %s\n" % entity.name)
        file.write("PORT (\n")
        nb_wires = len(entity.inputs) + len(entity.inouts) + len(entity.outputs)
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        file.write(");\n")
        file.write("END COMPONENT;\n")
        
        file.write("-- declare inputs and initialize them\n")     
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")

        file.write("-- declare inouts and initialize them\n")     
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")

        file.write("-- declare outputs and initialize them\n")               
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")
        
        file.write("constant clk_period : time := %s ns;\n" % clk_period)               
        file.write("\n")
        file.write("BEGIN\n") 
        file.write("-- Instantiate the Unit Under Test (UUT)\n")           
        file.write("uut: %s PORT MAP (\n" % entity.name)
        nb_wires = len(entity.inputs) + len(entity.inouts) + len(entity.outputs)
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")                
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")    
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")    
        file.write(");\n")
        file.write("-- Clock process definitions( clock with 50% duty cycle is generated here.)\n")   

        file.write("clk_process :process\n")
        file.write("begin\n    <clk_a_remplacer> <= '0';\n")
        file.write("    wait for clk_period/2;  --for %s ns signal is '0'.\n" % clk_period_2)
        file.write("    <clk_a_remplacer> <= '1';\n")
        file.write("    wait for clk_period/2;  --for %s ns signal is '1'.\n" % clk_period_2)
        file.write("end process;\n")
        file.write("-- Stimulus process\nstim_proc: process\nbegin\n")
        file.write("wait for 3*clk_period;\n")
        file.write("-- Insert your tests\n")               
        file.write("   wait;\nend process;\nEND;")              
        file.close()

    def wire_to_text(self, da_wire, last_one):
        if da_wire.nb_wires == 1:
            text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " + da_wire.written_term
        else:
            if da_wire.to == True:
                text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " +\
                    da_wire.written_term + "(%s" % da_wire.stop + " to " +\
                    "%s)" % da_wire.start
            else:
                text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " +\
                    da_wire.written_term + "(%s" % da_wire.start + " downto " +\
                    "%s)" % da_wire.stop 
        if last_one : 
            return text + ";"
        else:
            return text

    def wire_to_signal(self, da_wire):
        if da_wire.nb_wires == 1:
            text = "    signal " + da_wire.name + " : " + da_wire.written_term
        else:
            if da_wire.to == True:
                text = "    signal " + da_wire.name + " : " +\
                    da_wire.written_term + "(%s" % da_wire.stop + " to " +\
                    "%s)" % da_wire.start
            else:
                text = "    signal " + da_wire.name + " : " +\
                    da_wire.written_term + "(%s" % da_wire.start + " downto " +\
                    "%s)" % da_wire.stop 
        return text + ";"
        

class PdfDrawer:

    def __init__(self, filename, entity, options):
        self.color = (0, 0, 0)
        self.factor = 1
        self.background_color = (0, 0, 0)
        self.analyse_options(options)

        self.surface = cairo.SVGSurface(filename, 10, 10)
        self.context = cairo.Context(self.surface)

        self.factor = 1
        self.height = self.compute_height(entity)
        self.width = self.compute_width(entity)
        if options.format.lower() == "svg":
            self.factor = 1
            self.surface = cairo.SVGSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "pdf":
            self.factor = 1
            self.surface = cairo.PDFSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "ps":
            self.factor = 1
            self.surface = cairo.PSSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "png":
            self.factor = float(
                options.width / (self.width + self.factor * line_length * 2 + self.factor * bbox_w_margin * 2))

            stride = cairo.ImageSurface.format_stride_for_width(
                cairo.FORMAT_ARGB32, 10000)
            data = bytearray(stride * 10000)
            # stride = cairo.ImageSurface.format_stride_for_width(cairo.FORMAT_ARGB32, int(self.width)+1)
            # data = bytearray(stride * int(self.height))

            self.surface = cairo.ImageSurface(
                cairo.FORMAT_ARGB32, int(self.factor * self.width + self.factor * line_length * 2 + self.factor * bbox_w_margin * 2), int(self.factor * self.height + self.factor * bbox_h_margin * 2), data, stride)

        self.context = cairo.Context(self.surface)
        self.draw_background(self.context)
        self.draw_entity(entity)

        self.surface.write_to_png(options.filename)

    def analyse_options(self, options):

        try:
            self.color = Color(options.color).rgb
        except:
            if options.verbose == True:
                print " **** Unknow color : revert to black **** "
            self.color = Color("black").rgb

        try:
            self.background_color = Color(options.background_color).rgb
        except:
            if options.verbose == True:
                print " **** Unknow color : revert to white (background) **** "
            self.background_color = Color("white").rgb

        self.transparency = options.transparency

    def draw_background(self, context):
        with context:
            context.set_source_rgba(self.background_color[0], self.background_color[
                                    1], self.background_color[2], self.transparency)
            context.paint()
        pass

    def set_source_color(self, color):
        self.context.set_source_rgba(color[0], color[1], color[2], 1)
        pass

    def go_invisible(self):
        self.context.set_source_rgba(0, 0, 0, 0)

    def draw_not(self, x, y, radius):
        self.go_invisible()
        self.context.stroke()
        self.context.arc(x, y, radius, 0, 2 * 3.14169)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_clk(self, x, y):
        self.context.move_to(x, y - self.factor * 5)
        self.context.rel_line_to(self.factor * 5, self.factor * 5)
        self.context.rel_line_to(-self.factor * 5, self.factor * 5)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_entity(self, entity):
        pos_x = self.factor * bbox_w_margin + self.factor * line_length
        pos_y = self.factor * bbox_h_margin
        height = self.compute_height(entity)
        width = self.compute_width(entity)
        self.draw_entity_box(pos_x, pos_y, width, height, self.factor * radius)
        self.draw_entity_name(entity.name, pos_x, pos_y, width)

        for i in range(0, len(entity.inputs)):
            self.draw_wire(
                entity.inputs[i], i + 1, pos_x - self.factor * radius)

        for i in range(0, len(entity.inouts)):
            self.draw_wire(
                entity.inouts[i], len(entity.inputs) + i + 1, pos_x - self.factor * radius)

        for i in range(0, len(entity.outputs)):
            self.draw_wire(
                entity.outputs[i], i + 1, pos_x + width + self.factor * radius)
        pass

    def draw_entity_box(self, x, y, width, height, radius):
        self.context.set_line_width(self.factor * line_width * 2)
        self.go_invisible()
        self.context.stroke()
        self.context.arc(x, y, radius, 3.14169, -0.5 * 3.14169)
        self.context.rel_line_to(width, 0)
        self.context.arc(x + width, y, radius, -0.5 * 3.14169, 0 * 3.14169)
        self.context.rel_line_to(0, height)
        self.context.arc(
            x + width, y + height, radius, 0 * 3.14169, 0.5 * 3.14169)
        self.context.rel_line_to(-width, 0)
        self.context.arc(x, y + height, radius, 0.5 * 3.14169, 1 * 3.14169)
        self.context.rel_line_to(0, -height)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_entity_name(self, name, x, y, box_width):
        self.set_font()
        with self.context:
            self.context.select_font_face(default_font, 1, 1)
            (x_bearing, y_bearing, width, height, x_advance,
             y_advance) = self.context.text_extents(name)
            delta = (x_bearing, y_bearing, width, height, x_advance, y_advance)
            self.context.move_to(x + box_width / 2 - width / 2, y + height)
            self.context.show_text(name)

    def compute_height(self, entity):
        height = max(
            len(entity.inputs) + len(entity.inouts), len(entity.outputs))
        if len(entity.inouts) == 0:
            return height * self.factor * rank_separation + self.factor * rank_top_margin
        else:
            return height * self.factor * rank_separation + self.factor * rank_top_margin + self.factor * inout_margin

    def compute_width(self, entity):
        maximum_width_left = -1
        maximum_width_right = -1
        self.set_font()
        for i in range(0, len(entity.inputs)):
            size = self.context.text_extents(entity.inputs[i].name)[4]
            if maximum_width_left < size:
                maximum_width_left = size

        for i in range(0, len(entity.inouts)):
            size = self.context.text_extents(entity.inouts[i].name)[4]
            if maximum_width_left < size:
                maximum_width_left = size

        for i in range(0, len(entity.outputs)):
            size = self.context.text_extents(entity.outputs[i].name)[4]
            if maximum_width_right < size:
                maximum_width_right = size

        title_size = self.context.text_extents(entity.name)[4]
        global_width = max(
            maximum_width_left + maximum_width_right + self.factor * 20, title_size + self.factor * 20)

        return global_width

    def draw_wire(self, wire, rank, pos_x):
        self.go_invisible()

        self.context.stroke()
        self.set_source_color(self.color)

        self.set_font()
        self.context.set_line_width(self.factor * line_width)

        y_pos = self.factor * rank_top_margin + \
            self.factor * rank * rank_separation
        if wire.dir == "inout":
            y_pos += self.factor * inout_margin
        if wire.dir == "in" or wire.dir == "inout":

            self.context.move_to(pos_x, y_pos)
            self.context.rel_line_to(-self.factor * line_length, 0)

            if wire.type == "clk":
                self.draw_clk(pos_x, y_pos)

            if wire.nb_wires != 1:
                self.context.move_to(
                    pos_x - self.factor * line_length / 2 + self.factor * multi_wire_symbol_size / 2, y_pos - self.factor * multi_wire_symbol_size / 2)
                self.context.rel_line_to(-self.factor * multi_wire_symbol_size,
                                         self.factor * multi_wire_symbol_size)
                label = "%s" % wire.nb_wires
                with self.context:
                    self.context.set_font_size(self.factor * 8)
                    wire_size = self.context.text_extents(label)[4]
                    height = self.context.text_extents(label)[3]
                    self.context.move_to(
                        pos_x - self.factor * line_length / 2 - wire_size / 2, y_pos - height)
                    self.context.show_text(label)

            self.context.move_to(
                pos_x + self.factor * wire_name_margin, y_pos + self.factor * multi_wire_symbol_size / 2)

        if wire.dir == "out":

            self.context.move_to(pos_x, y_pos)
            self.context.rel_line_to(self.factor * line_length, 0)
            size = self.context.text_extents(wire.name)[4]

            if wire.nb_wires != 1:
                x_pos = pos_x + self.factor * line_length / \
                    2 + self.factor * multi_wire_symbol_size / 2
                self.context.move_to(
                    x_pos, y_pos - self.factor * multi_wire_symbol_size / 2)
                self.context.rel_line_to(-self.factor * multi_wire_symbol_size,
                                         self.factor * multi_wire_symbol_size)
                label = "%s" % wire.nb_wires
                with self.context:
                    self.context.set_font_size(self.factor * 8)
                    wire_size = self.context.text_extents(label)[4]
                    height = self.context.text_extents(label)[3]
                    self.context.move_to(
                        x_pos - self.factor * multi_wire_symbol_size / 2 - wire_size / 2, y_pos - height)
                    self.context.show_text(label)

            self.context.move_to(
                pos_x - self.factor * wire_name_margin - size, y_pos + self.factor * multi_wire_symbol_size / 2)

        self.context.show_text(wire.name)
        self.context.stroke()

    def set_font(self):
        self.set_source_color(self.color)
        self.context.select_font_face(default_font, 0, 0)
        self.context.set_font_size(self.factor * 12)
<commit_msg>PAssage de Entity en Majuscule<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

import cairocffi as cairo
from tools.options import Options
from colour import Color
from vhdl_objects.wire import Wire

#default_font = 'Aegyptus'
default_font = 'jura'

radius = 3
rank_separation = 15
rank_top_margin = 20
line_length = 35
inout_margin = 7

bbox_w_margin = 7
bbox_h_margin = 7

multi_wire_symbol_size = 6
line_width = 1.0

wire_name_margin = 8

clk_period = 10
clk_period_2 = clk_period/2

class TestBenchGenerator:

    def __init__(self, filename, entity):
        file = open(filename, "w")
        file.write("-- This testBench was generated by pyVhdl2Sch --\n")
        file.write("LIBRARY ieee;\n")
        file.write("USE ieee.std_logic_1164.ALL;\n")
        file.write("USE ieee.std_logic_unsigned.all;\n\n")
        file.write("\n")
        file.write("-- entity declaration\n")
        file.write("ENTITY tb_%s IS\n" % entity.name)
        file.write("END tb_%s;\n\n" % entity.name)
        file.write("ARCHITECTURE behavior OF tb_%s IS\n" % entity.name)
        file.write("-- Component Declaration for the Unit Under Test (UUT)\n")
        file.write("COMPONENT %s\n" % entity.name)
        file.write("PORT (\n")
        nb_wires = len(entity.inputs) + len(entity.inouts) + len(entity.outputs)
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_text(da_wire, nb_wires) + "\n")
        file.write(");\n")
        file.write("END COMPONENT;\n")
        
        file.write("-- declare inputs and initialize them\n")     
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")

        file.write("-- declare inouts and initialize them\n")     
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")

        file.write("-- declare outputs and initialize them\n")               
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write(self.wire_to_signal(da_wire) + "\n")
        
        file.write("constant clk_period : time := %s ns;\n" % clk_period)               
        file.write("\n")
        file.write("BEGIN\n") 
        file.write("-- Instantiate the Unit Under Test (UUT)\n")           
        file.write("uut: %s PORT MAP (\n" % entity.name)
        nb_wires = len(entity.inputs) + len(entity.inouts) + len(entity.outputs)
        for da_wire in entity.inputs:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")                
        for da_wire in entity.inouts:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")    
        for da_wire in entity.outputs:
            nb_wires = nb_wires-1
            file.write("    " + da_wire.name + " => " + da_wire.name) 
            if nb_wires:
                file.write(",\n")
            else:
                file.write("\n")    
        file.write(");\n")
        file.write("-- Clock process definitions( clock with 50% duty cycle is generated here.)\n")   

        file.write("clk_process :process\n")
        file.write("begin\n    <clk_a_remplacer> <= '0';\n")
        file.write("    wait for clk_period/2;  --for %s ns signal is '0'.\n" % clk_period_2)
        file.write("    <clk_a_remplacer> <= '1';\n")
        file.write("    wait for clk_period/2;  --for %s ns signal is '1'.\n" % clk_period_2)
        file.write("end process;\n")
        file.write("-- Stimulus process\nstim_proc: process\nbegin\n")
        file.write("wait for 3*clk_period;\n")
        file.write("-- Insert your tests\n")               
        file.write("   wait;\nend process;\nEND;")              
        file.close()

    def wire_to_text(self, da_wire, last_one):
        if da_wire.nb_wires == 1:
            text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " + da_wire.written_term
        else:
            if da_wire.to == True:
                text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " +\
                    da_wire.written_term + "(%s" % da_wire.stop + " to " +\
                    "%s)" % da_wire.start
            else:
                text = "    " + da_wire.name + " : " + da_wire.dir.upper() + " " +\
                    da_wire.written_term + "(%s" % da_wire.start + " downto " +\
                    "%s)" % da_wire.stop 
        if last_one : 
            return text + ";"
        else:
            return text

    def wire_to_signal(self, da_wire):
        if da_wire.nb_wires == 1:
            text = "    signal " + da_wire.name + " : " + da_wire.written_term
        else:
            if da_wire.to == True:
                text = "    signal " + da_wire.name + " : " +\
                    da_wire.written_term + "(%s" % da_wire.stop + " to " +\
                    "%s)" % da_wire.start
            else:
                text = "    signal " + da_wire.name + " : " +\
                    da_wire.written_term + "(%s" % da_wire.start + " downto " +\
                    "%s)" % da_wire.stop 
        return text + ";"
        

class PdfDrawer:

    def __init__(self, filename, entity, options):
        self.color = (0, 0, 0)
        self.factor = 1
        self.background_color = (0, 0, 0)
        self.analyse_options(options)

        self.surface = cairo.SVGSurface(filename, 10, 10)
        self.context = cairo.Context(self.surface)

        self.factor = 1
        self.height = self.compute_height(entity)
        self.width = self.compute_width(entity)
        if options.format.lower() == "svg":
            self.factor = 1
            self.surface = cairo.SVGSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "pdf":
            self.factor = 1
            self.surface = cairo.PDFSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "ps":
            self.factor = 1
            self.surface = cairo.PSSurface(
                filename, self.width + line_length * 2 + bbox_w_margin * 2, self.height + bbox_h_margin * 2)

        if options.format.lower() == "png":
            self.factor = float(
                options.width / (self.width + self.factor * line_length * 2 + self.factor * bbox_w_margin * 2))

            stride = cairo.ImageSurface.format_stride_for_width(
                cairo.FORMAT_ARGB32, 10000)
            data = bytearray(stride * 10000)
            # stride = cairo.ImageSurface.format_stride_for_width(cairo.FORMAT_ARGB32, int(self.width)+1)
            # data = bytearray(stride * int(self.height))

            self.surface = cairo.ImageSurface(
                cairo.FORMAT_ARGB32, int(self.factor * self.width + self.factor * line_length * 2 + self.factor * bbox_w_margin * 2), int(self.factor * self.height + self.factor * bbox_h_margin * 2), data, stride)

        self.context = cairo.Context(self.surface)
        self.draw_background(self.context)
        self.draw_entity(entity)

        self.surface.write_to_png(options.filename)

    def analyse_options(self, options):

        try:
            self.color = Color(options.color).rgb
        except:
            if options.verbose == True:
                print " **** Unknow color : revert to black **** "
            self.color = Color("black").rgb

        try:
            self.background_color = Color(options.background_color).rgb
        except:
            if options.verbose == True:
                print " **** Unknow color : revert to white (background) **** "
            self.background_color = Color("white").rgb

        self.transparency = options.transparency

    def draw_background(self, context):
        with context:
            context.set_source_rgba(self.background_color[0], self.background_color[
                                    1], self.background_color[2], self.transparency)
            context.paint()
        pass

    def set_source_color(self, color):
        self.context.set_source_rgba(color[0], color[1], color[2], 1)
        pass

    def go_invisible(self):
        self.context.set_source_rgba(0, 0, 0, 0)

    def draw_not(self, x, y, radius):
        self.go_invisible()
        self.context.stroke()
        self.context.arc(x, y, radius, 0, 2 * 3.14169)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_clk(self, x, y):
        self.context.move_to(x, y - self.factor * 5)
        self.context.rel_line_to(self.factor * 5, self.factor * 5)
        self.context.rel_line_to(-self.factor * 5, self.factor * 5)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_entity(self, entity):
        pos_x = self.factor * bbox_w_margin + self.factor * line_length
        pos_y = self.factor * bbox_h_margin
        height = self.compute_height(entity)
        width = self.compute_width(entity)
        self.draw_entity_box(pos_x, pos_y, width, height, self.factor * radius)
        self.draw_entity_name(entity.name, pos_x, pos_y, width)

        for i in range(0, len(entity.inputs)):
            self.draw_wire(
                entity.inputs[i], i + 1, pos_x - self.factor * radius)

        for i in range(0, len(entity.inouts)):
            self.draw_wire(
                entity.inouts[i], len(entity.inputs) + i + 1, pos_x - self.factor * radius)

        for i in range(0, len(entity.outputs)):
            self.draw_wire(
                entity.outputs[i], i + 1, pos_x + width + self.factor * radius)
        pass

    def draw_entity_box(self, x, y, width, height, radius):
        self.context.set_line_width(self.factor * line_width * 2)
        self.go_invisible()
        self.context.stroke()
        self.context.arc(x, y, radius, 3.14169, -0.5 * 3.14169)
        self.context.rel_line_to(width, 0)
        self.context.arc(x + width, y, radius, -0.5 * 3.14169, 0 * 3.14169)
        self.context.rel_line_to(0, height)
        self.context.arc(
            x + width, y + height, radius, 0 * 3.14169, 0.5 * 3.14169)
        self.context.rel_line_to(-width, 0)
        self.context.arc(x, y + height, radius, 0.5 * 3.14169, 1 * 3.14169)
        self.context.rel_line_to(0, -height)
        self.set_source_color(self.color)
        self.context.stroke()

    def draw_entity_name(self, name, x, y, box_width):
        self.set_font()
        with self.context:
            self.context.select_font_face(default_font, 1, 1)
            (x_bearing, y_bearing, width, height, x_advance,
             y_advance) = self.context.text_extents(name)
            delta = (x_bearing, y_bearing, width, height, x_advance, y_advance)
            self.context.move_to(x + box_width / 2 - width / 2, y + height)
            self.context.show_text(name)

    def compute_height(self, entity):
        height = max(
            len(entity.inputs) + len(entity.inouts), len(entity.outputs))
        if len(entity.inouts) == 0:
            return height * self.factor * rank_separation + self.factor * rank_top_margin
        else:
            return height * self.factor * rank_separation + self.factor * rank_top_margin + self.factor * inout_margin

    def compute_width(self, entity):
        maximum_width_left = -1
        maximum_width_right = -1
        self.set_font()
        for i in range(0, len(entity.inputs)):
            size = self.context.text_extents(entity.inputs[i].name)[4]
            if maximum_width_left < size:
                maximum_width_left = size

        for i in range(0, len(entity.inouts)):
            size = self.context.text_extents(entity.inouts[i].name)[4]
            if maximum_width_left < size:
                maximum_width_left = size

        for i in range(0, len(entity.outputs)):
            size = self.context.text_extents(entity.outputs[i].name)[4]
            if maximum_width_right < size:
                maximum_width_right = size

        title_size = self.context.text_extents(entity.name)[4]
        global_width = max(
            maximum_width_left + maximum_width_right + self.factor * 20, title_size + self.factor * 20)

        return global_width

    def draw_wire(self, wire, rank, pos_x):
        self.go_invisible()

        self.context.stroke()
        self.set_source_color(self.color)

        self.set_font()
        self.context.set_line_width(self.factor * line_width)

        y_pos = self.factor * rank_top_margin + \
            self.factor * rank * rank_separation
        if wire.dir == "inout":
            y_pos += self.factor * inout_margin
        if wire.dir == "in" or wire.dir == "inout":

            self.context.move_to(pos_x, y_pos)
            self.context.rel_line_to(-self.factor * line_length, 0)

            if wire.type == "clk":
                self.draw_clk(pos_x, y_pos)

            if wire.nb_wires != 1:
                self.context.move_to(
                    pos_x - self.factor * line_length / 2 + self.factor * multi_wire_symbol_size / 2, y_pos - self.factor * multi_wire_symbol_size / 2)
                self.context.rel_line_to(-self.factor * multi_wire_symbol_size,
                                         self.factor * multi_wire_symbol_size)
                label = "%s" % wire.nb_wires
                with self.context:
                    self.context.set_font_size(self.factor * 8)
                    wire_size = self.context.text_extents(label)[4]
                    height = self.context.text_extents(label)[3]
                    self.context.move_to(
                        pos_x - self.factor * line_length / 2 - wire_size / 2, y_pos - height)
                    self.context.show_text(label)

            self.context.move_to(
                pos_x + self.factor * wire_name_margin, y_pos + self.factor * multi_wire_symbol_size / 2)

        if wire.dir == "out":

            self.context.move_to(pos_x, y_pos)
            self.context.rel_line_to(self.factor * line_length, 0)
            size = self.context.text_extents(wire.name)[4]

            if wire.nb_wires != 1:
                x_pos = pos_x + self.factor * line_length / \
                    2 + self.factor * multi_wire_symbol_size / 2
                self.context.move_to(
                    x_pos, y_pos - self.factor * multi_wire_symbol_size / 2)
                self.context.rel_line_to(-self.factor * multi_wire_symbol_size,
                                         self.factor * multi_wire_symbol_size)
                label = "%s" % wire.nb_wires
                with self.context:
                    self.context.set_font_size(self.factor * 8)
                    wire_size = self.context.text_extents(label)[4]
                    height = self.context.text_extents(label)[3]
                    self.context.move_to(
                        x_pos - self.factor * multi_wire_symbol_size / 2 - wire_size / 2, y_pos - height)
                    self.context.show_text(label)

            self.context.move_to(
                pos_x - self.factor * wire_name_margin - size, y_pos + self.factor * multi_wire_symbol_size / 2)

        self.context.show_text(wire.name)
        self.context.stroke()

    def set_font(self):
        self.set_source_color(self.color)
        self.context.select_font_face(default_font, 0, 0)
        self.context.set_font_size(self.factor * 12)

{'fraction_non_alphanumeric': 0.11965865399643649, 'fraction_numerical': 0.014441561689225094, 'mean_word_length': 1.8485442079957262, 'pattern_counts': {'":': 16, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2844841', 'n_tokens_mistral': 10654, 'n_tokens_neox': 10055, 'n_words': 1994}