Skip to content

Commit

Permalink
Starting to add a "generic" process technology.
Browse files Browse the repository at this point in the history
Signed-off-by: Tim 'mithro' Ansell <[email protected]>
  • Loading branch information
mithro committed Sep 19, 2023
1 parent 22e7acc commit 1050920
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 0 deletions.
31 changes: 31 additions & 0 deletions verilog/generic.bb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
(* blackbox *)
module and2(input A1, A2, output Z);
endmodule

(* blackbox *)
module xor2(input A1, A2, output Z);
endmodule

(* blackbox *)
module inv(input I, output ZN);
endmodule

(* blackbox *)
module addf(input A, B, CI, output CO, S);
endmodule

(* blackbox *)
module addh(input A, B, output CO, S);
endmodule

(* blackbox *)
module ao21(input A1, A2, B, output Z);
endmodule

(* blackbox *)
module ao22(input A1, A2, B1, B2, output Z);
endmodule

(* blackbox *)
module oai33(input A1, A2, A3, B1, B2, B3, output ZN);
endmodule
172 changes: 172 additions & 0 deletions verilog/generic.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
module and2( A1, A2, Z );
input A1, A2;
output Z;

and MGM_BG_0( Z, A1, A2 );
endmodule

module xor2( A2, A1, Z );
input A1, A2;
output Z;

wire A2_inv_for_xor2;
not MGM_BG_0( A2_inv_for_xor2, A2 );

wire Z_row1;
and MGM_BG( Z_row1, A2_inv_for_xor2, A1 );

wire A1_inv_for_xor2;
not MGM_BG_2( A1_inv_for_xor2, A1 );

wire Z_row2;
and MGM_BG_3( Z_row2, A1_inv_for_xor2, A2 );
or MGM_BG_4( Z, Z_row1, Z_row2 );

endmodule

module inv( I, ZN );
input I;
output ZN;

not MGM_BG_0( ZN, I );
endmodule

module addf( S, A, CI, B, CO );
input A, B, CI;
output CO, S;

wire CO_row1;
and MGM_BG_0( CO_row1, A, B );

wire CO_row2;
and MGM_BG( CO_row2, A, CI );

wire CO_row3;
and MGM_BG_2( CO_row3, B, CI );
or MGM_BG_3( CO, CO_row1, CO_row2, CO_row3 );

wire S_row1;
and MGM_BG_4( S_row1, A, B, CI );

wire B_inv_for_addf;
not MGM_BG_5( B_inv_for_addf, B );

wire CI_inv_for_addf;
not MGM_BG_6( CI_inv_for_addf, CI );

wire S_row2;
and MGM_BG_7( S_row2, B_inv_for_addf, CI_inv_for_addf, A );

wire A_inv_for_addf;
not MGM_BG_8( A_inv_for_addf, A );

wire S_row3;
and MGM_BG_9( S_row3, A_inv_for_addf, CI_inv_for_addf, B );

wire S_row4;
and MGM_BG0( S_row4, A_inv_for_addf, B_inv_for_addf, CI );
or MGM_BG1( S, S_row1, S_row2, S_row3, S_row4 );
endmodule

module addh( CO, A, B, S );
input A, B;
output CO, S;

and MGM_BG_0( CO, A, B );

wire B_inv_for_addh;
not MGM_BG( B_inv_for_addh, B );

wire S_row1;
and MGM_BG_2( S_row1, B_inv_for_addh, A );

wire A_inv_for_addh;
not MGM_BG_3( A_inv_for_addh, A );

wire S_row2;
and MGM_BG_4( S_row2, A_inv_for_addh, B );
or MGM_BG_5( S, S_row1, S_row2 );
endmodule

// FIXME: Convert to aoi21
module aoi21( A2, ZN, A1, B );
input A1, A2, B;
output ZN;

wire A1_inv_for_aoi21;
not MGM_BG_0( A1_inv_for_aoi21, A1 );

wire B_inv_for_aoi21;
not MGM_BG( B_inv_for_aoi21, B );

wire ZN_row1;
and MGM_BG_2( ZN_row1, A1_inv_for_aoi21, B_inv_for_aoi21 );

wire A2_inv_for_aoi21;
not MGM_BG_3( A2_inv_for_aoi21, A2 );

wire ZN_row2;
and MGM_BG_4( ZN_row2, A2_inv_for_aoi21, B_inv_for_aoi21 );
or MGM_BG_5( ZN, ZN_row1, ZN_row2 );
endmodule

// FIXME: Convert to ao22
module aoi22( B2, B1, ZN, A1, A2 );
input A1, A2, B1, B2;
output ZN;

wire A1_inv_for_aoi22;
not MGM_BG_0( A1_inv_for_aoi22, A1 );

wire B1_inv_for_aoi22;
not MGM_BG( B1_inv_for_aoi22, B1 );

wire ZN_row1;
and MGM_BG_2( ZN_row1, A1_inv_for_aoi22, B1_inv_for_aoi22 );

wire B2_inv_for_aoi22;
not MGM_BG_3( B2_inv_for_aoi22, B2 );

wire ZN_row2;
and MGM_BG_4( ZN_row2, A1_inv_for_aoi22, B2_inv_for_aoi22 );

wire A2_inv_for_aoi22;
not MGM_BG_5( A2_inv_for_aoi22, A2 );

wire ZN_row3;
and MGM_BG_6( ZN_row3, A2_inv_for_aoi22, B1_inv_for_aoi22 );

wire ZN_row4;
and MGM_BG_7( ZN_row4, A2_inv_for_aoi22, B2_inv_for_aoi22 );
or MGM_BG_8( ZN, ZN_row1, ZN_row2, ZN_row3, ZN_row4 );
endmodule

module oai33( B3, B2, B1, ZN, A1, A2, A3 );
input A1, A2, A3, B1, B2, B3;
output ZN;

wire A1_inv_for_oai33;
not MGM_BG_0( A1_inv_for_oai33, A1 );

wire A2_inv_for_oai33;
not MGM_BG( A2_inv_for_oai33, A2 );

wire A3_inv_for_oai33;
not MGM_BG_2( A3_inv_for_oai33, A3 );

wire ZN_row1;
and MGM_BG_3( ZN_row1, A1_inv_for_oai33, A2_inv_for_oai33, A3_inv_for_oai33 );

wire B1_inv_for_oai33;
not MGM_BG_4( B1_inv_for_oai33, B1 );

wire B2_inv_for_oai33;
not MGM_BG_5( B2_inv_for_oai33, B2 );

wire B3_inv_for_oai33;
not MGM_BG_6( B3_inv_for_oai33, B3 );

wire ZN_row2;
and MGM_BG_7( ZN_row2, B1_inv_for_oai33, B2_inv_for_oai33, B3_inv_for_oai33 );
or MGM_BG_8( ZN, ZN_row1, ZN_row2 );
endmodule
112 changes: 112 additions & 0 deletions vlsiffra/tech/generic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from amaranth import Elaboratable, Instance


class GenericProcess(Elaboratable):

""" Maps to a set of generic cell names. """

def _PoweredInstance(self, *args, **kwargs):
if self._powered:
kwargs.update({
"i_VDD": self.VPWR,
"i_VSS": self.VGND,
})
return Instance(*args, **kwargs)

def _generate_and(self, a, b, o):
andgate = self._PoweredInstance(
"and2",
i_A1=a,
i_A2=b,
o_Z=o
)

self.m.submodules += andgate

def _generate_xor(self, a, b, o):
xorgate = self._PoweredInstance(
"xor2",
i_A1=a,
i_A2=b,
o_Z=o
)

self.m.submodules += xorgate

def _generate_inv(self, a, o):
invgate = self._PoweredInstance(
"inv",
i_I=a,
o_ZN=o
)

self.m.submodules += invgate

def _generate_full_adder(self, a, b, carry_in, sum_out, carry_out, name=None):
fa = self._PoweredInstance(
"addf",
o_CO=carry_out,
o_S=sum_out,
i_A=a,
i_B=b,
i_CI=carry_in
)
if name:
self.m.submodules[name] = fa
else:
self.m.submodules += fa

def _generate_half_adder(self, a, b, sum_out, carry_out, name=None):
ha = self._PoweredInstance(
"addh",
o_CO=carry_out,
o_S=sum_out,
i_A=a,
i_B=b
)

if name:
self.m.submodules[name] = ha
else:
self.m.submodules += ha

# Used in adder
def _generate_ao21(self, a1, a2, b1, o):
""" 2-input AND into first input of 2-input OR. """
ao21gate = self._PoweredInstance(
"ao21",
i_A1=a1,
i_A2=a2,
i_B=b1,
o_Z=o
)
self.m.submodules += ao21gate

# Used in multiplier
def _generate_ao22(self, a1, a2, b1, b2, o):
""" 2-input AND into both inputs of 2-input OR. """
ao22gate = self._PoweredInstance(
"ao22",
i_A1=a1,
i_A2=a2,
i_B1=b1,
i_B2=b2,
o_Z=o
)
self.m.submodules += ao22gate

# Used in multiplier
def _generate_oai33(self, a1, a2, a3, b1, b2, b3, o):
""" 2 3-input OR into 2-input NAND. """
oai33gate = self._PoweredInstance(
"oai33",
i_A1=a1,
i_A2=a2,
i_A3=a3,
i_B1=b1,
i_B2=b2,
i_B3=b3,
o_ZN=o
)

self.m.submodules += oai33gate

0 comments on commit 1050920

Please sign in to comment.