Ejemplo n.º 1
0
 def run(code):
     return toolchain.run(
         f"module top(input C2, R, output Q); {code} endmodule", {
             'C2': pinout['C2'],
             'R': pinout['R'],
             'Q': pinout[macrocell['pad']],
         }, f"{device_name}-{package}")
Ejemplo n.º 2
0
        def run_pads(pad_names):
            ports = []
            cells = []
            pins = {}

            used_pads = set(pad_names)
            for n, pad_name in enumerate(pad_names):
                for other_macrocell_name, other_macrocell in device[
                        'macrocells'].items():
                    if (other_macrocell['pad'] not in used_pads
                            and other_macrocell['pad'] in pinout):
                        used_pads.add(other_macrocell['pad'])
                        break
                else:
                    assert False

                ports += [f"input OE{n}", f"output O{n}"]
                cells += [
                    f"wire Q{n}; DFFAS dff{n}(1'b0, O{n}, 1'b0, Q{n}); ",
                    f"TRI t{n}(Q{n}, OE{n}, O{n}); "
                ]
                pins.update({
                    f"O{n}": pinout[other_macrocell['pad']],
                    f"OE{n}": pinout[pad_name],
                })

            return toolchain.run(
                f"module top({', '.join(ports)}); "
                f"{' '.join(cells)} "
                f"endmodule", pins, f"{device_name}-{package}")
Ejemplo n.º 3
0
        def run(nets, probe_macrocell, *, invert=False):
            pads = [net[:-4] for net in nets if net.endswith("_PAD")]
            fbs = [net[:-3] for net in nets if net.endswith("_FB")]
            sigs = pads + fbs

            ins = [f"input {pad}" for pad in pads]
            bffs = [
                f"wire {fb}; DFF fb_{fb}(1'b0, 1'b0, {fb}); " for fb in fbs
            ]
            ands = []

            # AND8 is advertised as a primitive but doesn't actually work in EDIF...
            ands.append(f"wire Y0; BUF b(1'b1, Y0); ")
            y_wire = "Y0"
            for n, off in enumerate(range(0, len(sigs), 3)):
                chunk = sigs[off:off + 3]
                last = (off + 3 >= len(sigs))
                ands.append(
                    f"wire Y{n+1}; AND{len(chunk) + 1}{'I1' if invert and last else ''} "
                    f"a_{n+1}(Y{n}, {', '.join(chunk)}, Y{n+1}); ")
                y_wire = f"Y{n+1}"

            return toolchain.run(
                f"module top(output Q, {', '.join(ins)}); "
                f"{' '.join(bffs)} "
                f"{' '.join(ands)} "
                f"DFF ff(1'b0, {y_wire}, Q); "
                f"endmodule", {
                    'Q': pinout[probe_macrocell['pad']],
                    **{pad: pinout[pad]
                       for pad in pads},
                    **{f"fb_{fb}": str(600 + int(fb[2:]))
                       for fb in fbs},
                }, f"{device_name}-{package}")
Ejemplo n.º 4
0
        def run(nets, probe_macrocell):
            pads = [net[:-4] for net in nets if net.endswith("_PAD")]
            fbs = [net[:-3] for net in nets if net.endswith("_FB")]
            sigs = pads + fbs

            ins = [f"input {pad}" for pad in pads]
            bffs = [
                f"wire {fb}; DFF fb_{fb}(1'b0, 1'b0, {fb}); " for fb in fbs
            ]
            ands = []

            # We need way too many inputs to rely on existing primitives.
            ands.append(f"wire Y0; BUF b(1'b1, Y0); ")
            y_wire = "Y0"
            for n, off in enumerate(range(0, len(sigs), 3)):
                chunk = sigs[off:off + 3]
                last = (off + 3 >= len(sigs))
                ands.append(f"wire Y{n+1}; AND{len(chunk) + 1} "
                            f"a_{n+1}(Y{n}, {', '.join(chunk)}, Y{n+1}); ")
                y_wire = f"Y{n+1}"

            return toolchain.run(
                f"module top(output Q, {', '.join(ins)}); "
                f"{' '.join(bffs)} "
                f"{' '.join(ands)} "
                f"DFF ff(1'b0, {y_wire}, Q); "
                f"endmodule", {
                    'Q': pinout[probe_macrocell['pad']],
                    **{pad: pinout[pad]
                       for pad in pads},
                    **{f"fb_{fb}": str(600 + int(fb[2:]))
                       for fb in fbs},
                }, f"{device_name}-{package}")
Ejemplo n.º 5
0
        def run(clocks, **kwargs):
            code = []
            outs = []
            for index, (pad_n, negedge) in enumerate(clocks):
                outs.append(f"Q{index}")
                if negedge:
                    code.append(
                        f"wire N{index}; INV in{index}(C{pad_n}, N{index}); "
                        f"DFFE ff{index}(N{index}, E1, 1'b0, Q{index});")
                else:
                    code.append(
                        f"DFFE ff{index}(C{pad_n}, E1, 1'b0, Q{index});")

            return toolchain.run(
                f"module top(input C1, C2, C3, E1, output QC, {', '.join(outs)}); "
                f"{' '.join(code)} "
                f"OR3 o(C1, C2, C3, QC); "
                f"endmodule", {
                    'C1': pinout['C1'],
                    'C2': pinout['C2'],
                    'C3': pinout[gclk3_pad],
                    'E1': pinout['E1'],
                    **{
                        out: pinout[macrocell['pad']]
                        for out, macrocell in zip(
                            outs, device['macrocells'].values())
                    },
                    'QC': pinout[device['macrocells']['MC8']['pad']],
                }, f"{device_name}-{package}", **kwargs)
Ejemplo n.º 6
0
 def run_pad(code, object, probe_macrocell):
     return toolchain.run(
         f"module top(input I, output Q); "
         f"{code} "
         f"endmodule", {
             'I': pinout[object['pad']],
             'Q': pinout[probe_macrocell['pad']],
         }, f"{device_name}-{package}")
Ejemplo n.º 7
0
 def run_fb(code, macrocell, probe_macrocell):
     return toolchain.run(
         f"module top(output Q); "
         f"wire I; DFF bff(1'b0, 1'b0, I);"
         f"{code} "
         f"endmodule", {
             'bff': str(600 + int(macrocell['pad'][1:])),
             'Q': pinout[probe_macrocell['pad']],
         }, f"{device_name}-{package}")
Ejemplo n.º 8
0
 def run(code):
     return toolchain.run(
         f"module top(input CLK1, CLK2, output O); "
         f"{code} "
         f"endmodule", {
             "CLK1": pinout['C1'],
             "CLK2": pinout['C2'],
             "O": pinout[macrocell['pad']],
         }, f"{device_name}-{package}")
Ejemplo n.º 9
0
 def run(code):
     return toolchain.run(
         f"module top(input CLK1); "
         f"wire Q, X, Y; OR2 o1(Q, X, Y); BUF b1(Y, X);"
         f"{code} "
         f"endmodule", {
             'CLK1': pinout['C1'],
             'ff': str(601 + macrocell_idx),
         }, f"{device_name}-{package}")
Ejemplo n.º 10
0
 def run_i(**kwargs):
     return toolchain.run(
         f"module top(input I1, I2, output O); OR2 o(I1, I2, O); endmodule",
         {
             'I1': pinout[macrocell['pad']],
             'I2': pinout[other_macrocell['pad']],
         },
         f"{device_name}-{package}",
         strategy=kwargs)
Ejemplo n.º 11
0
 def run(code, **kwargs):
     return toolchain.run(
         f"module top(input CLK, output O); "
         f"wire Q; TRI tri(Q, 1'b0, O); "
         f"{code} "
         f"endmodule", {
             'CLK': pinout['C1'],
             'ff': str(601 + macrocell_idx),
         }, f"{device_name}-{package}", **kwargs)
Ejemplo n.º 12
0
 def run(code):
     return toolchain.run(
         f"module top(input CLK1, CLK2, OE1, output Q);"
         f"{code}"
         f"endmodule", {
             'CLK1': pinout['C1'],
             'CLK2': pinout['C2'],
             'OE1': pinout['E1'],
             'Q': pinout[macrocell['pad']],
         }, f"{device_name}-{package}")
Ejemplo n.º 13
0
 def run(code="wire A, Q; BUF b(A, Q);", **kwargs):
     return toolchain.run(
         f"module top(input C1, C2, C3, A, output Q); "
         f"{code} "
         f"endmodule",
         {
             'C1': pinout['C1'],
             'C2': pinout['C2'],
             'C3': pinout[gclk3_pad],
         },
         f"{device_name}-{package}", **kwargs)
Ejemplo n.º 14
0
 def run(code):
     return toolchain.run(
         f"module top(input OE, CLK1, CLK2, CLK3, output O);"
         f"wire Q; TRI tri(Q, 1'b0, O); "
         f"{code} "
         f"endmodule", {
             'CLK1': pinout['C1'],
             'CLK2': pinout['C2'],
             'CLK3': pinout[gclk3_pad],
             'ff': str(601 + macrocell_idx),
         }, f"{device_name}-{package}")
Ejemplo n.º 15
0
 def run(code):
     return toolchain.run(
         f"module top(input CLK1, CLK2, output O); "
         f"{code} "
         f"endmodule", {
             "CLK1": pinout['C1'],
             "CLK2": pinout['C2'],
             "O": pinout[macrocell['pad']],
             "dff": str(601 + macrocell_idx),
         },
         f"{device_name}-{package}",
         strategy={"logic_doubling": "on"})
Ejemplo n.º 16
0
 def run(code, **kwargs):
     return toolchain.run(
         f"module top(input CLK1, {', '.join(goe_pads)}, output O); "
         f"wire Y; OR{len(goe_pads)+1} o({', '.join(goe_pads)}, CLK1, Y); "
         f"{code} "
         f"endmodule", {
             'O': pinout[macrocell['pad']],
             'CLK1': pinout['C1'],
             **{
                 goe_pad: pinout[goe_pad[:-4]]
                 for goe_pad in goe_pads
             },
         }, f"{device_name}-{package}", **kwargs)
Ejemplo n.º 17
0
 def run(code):
     return toolchain.run(
         f"module top(input C1, C2, E1, R, I, output Q); "
         f"{code} "
         f"endmodule", {
             'C1': pinout['C1'],
             'C2': pinout['C2'],
             'E1': pinout['E1'],
             'R': pinout['R'],
             'I': pinout[other_macrocell['pad']],
             'Q': pinout[macrocell['pad']],
         },
         f"{device_name}-{package}",
         strategy={'xor_synthesis': 'on'})
Ejemplo n.º 18
0
 def run(code):
     return toolchain.run(
         f"module top(input CLK1, OE1, ...); "
         f"{code} "
         f"endmodule", {
             'CLK1': pinout['C1'],
             'OE1': pinout['E1'],
             'IO': pinout[macrocell['pad']],
             'ff': str(601 + macrocell_idx),
         },
         f"{device_name}-{package}",
         strategy={
             "logic_doubling": "on",
             "fast_inlatch": "on"
         })
Ejemplo n.º 19
0
 def run(code, **kwargs):
     return toolchain.run(
         f"module top(input CLK1, CLK2, output O1, O2); "
         f"{code} "
         f"endmodule",
         {
             'CLK1': pinout['C1'],
             'CLK2': pinout['C2'],
             'O1': pinout[other1_macrocell['pad']],
             'O2': pinout[other2_macrocell['pad']],
             'dff1': str(601 + macrocell_idx),
             # Pretty gross to rely on autogenerated names, but the other
             # netlist/constraint sets I came up were even less reliable.
             'Com_Ctrl_13': str(601 + macrocell_idx),
         },
         f"{device_name}-{package}",
         **kwargs)
Ejemplo n.º 20
0
 def run(code):
     return toolchain.run(
         f"module top(input C1, C2, E1, R, output O); "
         f"wire Q; TRI tri(Q, 1'b0, O); "
         f"wire Y1, Y2, Y3; "
         f"AND2 a1(C1, C2, Y1); "
         f"AND2 a2(C2, E1, Y2); "
         f"AND2 a3(E1, R, Y3); "
         f"{code} "
         f"endmodule", {
             'C1': pinout['C1'],
             'C2': pinout['C2'],
             'E1': pinout['E1'],
             'R': pinout['R'],
             'ff': str(601 + macrocell_idx),
         },
         f"{device_name}-{package}",
         strategy={'xor_synthesis': 'on'})
Ejemplo n.º 21
0
 def run(code, **kwargs):
     return toolchain.run(
         f"module top(input GCLR, GCLK1, GCLK2, GCLK3, "
         f"           input GOE1, GOE2, GOE3, GOE4, GOE5, GOE6, "
         f"           output Q); "
         f"{code} "
         f"endmodule",
         {
             'GCLR':  pinout['R'],
             'GCLK1': pinout['C1'],
             'GCLK2': pinout['C2'],
             'GCLK3': pinout[gclk3_pad],
             **{
                 f"GOE{1+n}": pinout[pad[:-4]]
                 for n, pad in enumerate(goe_pads)
             },
             'Q': pinout[device['macrocells']['MC1']['pad']],
         },
         f"{device_name}-{package}", **kwargs)
Ejemplo n.º 22
0
 def run_fb(macrocell_idx, macrocell_name):
     for other1_macrocell_name, other1_macrocell in device[
             'macrocells'].items():
         if other1_macrocell_name != macrocell_name:
             break
     else:
         assert False
     for other2_macrocell_name, other2_macrocell in device[
             'macrocells'].items():
         if (other2_macrocell_name != macrocell_name
                 and other2_macrocell_name != other1_macrocell_name):
             break
     else:
         assert False
     pins = [
         f"OEA+:{pinout['C1']}", f"OEB+:{pinout['C2']}",
         f"Y0+:{pinout[device['macrocells'][other1_macrocell_name]['pad']]}",
         f"Y1+:{pinout[device['macrocells'][other2_macrocell_name]['pad']]}"
     ]
     return toolchain.run(f"""
         #$ PINS 4 {' '.join(pins)}
         #$ PROPERTY ATMEL Global_OE = Y0
         #$ PROPERTY ATMEL OE_node = {str(601 + macrocell_idx)}
         .i 2
         .o 4
         .type f
         .ilb  OEA OEB
         .ob   Y0 Y0.OE Y1 Y1.OE
         .phase 1111
         .p 2
         -- 0000
         00 0101
         .e
         """,
                          None,
                          f"{device_name}-{package}",
                          strategy={'logic_doubling': 'on'},
                          format='tt')
Ejemplo n.º 23
0
 def run_o(**kwargs):
     return toolchain.run(
         f"module top(output O); assign O = 1'b0; endmodule",
         {'O': pinout[macrocell['pad']]},
         f"{device_name}-{package}",
         strategy=kwargs)
Ejemplo n.º 24
0
                for index, macrocell_name in enumerate(device['macrocells'])
            }
            tt2 = foldback_tt2(src_nodes=[
                macrocell_nodes[macrocell_name]
                for macrocell_name in other_block['macrocells']
            ],
                               dst_nodes=[
                                   macrocell_nodes[macrocell_name]
                                   for macrocell_name in block['macrocells']
                               ])

            # The fitter completely disregards any `PINNODE 3xx = net;` constraints, and instead
            # assigns foldbacks consistently from last to first macrocell in the block. However,
            # the actual routing is somewhat random, so we have to examine all related pterms.
            f_prev = toolchain.run(tt2, {},
                                   f"{device_name}-{package}",
                                   format='tt')
            folds = []
            seen_pt1s = set()
            seen_pt4s = set()
            for index in range(len(block['macrocells'])):
                folds.append(f"FbY{1+index}")
                f_curr = toolchain.run(
                    tt2, {},
                    f"{device_name}-{package}",
                    format='tt',
                    strategy={'Foldback_Logic': ','.join(folds)})

                # The macrocell that gained a foldback now had PT1 enabled, find it.
                new_pt1s = set()
                for macrocell_name in block['macrocells']: