diff --git a/cells_sim.v b/cells_sim.v index 2858f06..0489697 100644 --- a/cells_sim.v +++ b/cells_sim.v @@ -22,6 +22,30 @@ module GAL_SOP (A, Y); end endmodule +module GAL_1SOP (A, Y); + parameter WIDTH = 0; + parameter DEPTH = 0; + parameter TABLE = 0; + + input [WIDTH-1:0] A; + output reg Y; + + integer i, j; + reg match; + + always @* begin + Y = 0; + for (i = 0; i < DEPTH; i=i+1) begin + match = 1; + for (j = 0; j < WIDTH; j=j+1) begin + if (TABLE[2*WIDTH*i + 2*j + 0] && A[j]) match = 0; + if (TABLE[2*WIDTH*i + 2*j + 1] && !A[j]) match = 0; + end + if (match) Y = 1; + end + end +endmodule + module GAL_INPUT (A, Y); input A; output Y; diff --git a/extractions/olmc.v b/extractions/olmc.v deleted file mode 100644 index e5e89ff..0000000 --- a/extractions/olmc.v +++ /dev/null @@ -1,15 +0,0 @@ -module REG_OUT_P (C, A, Y); - input C, A; - output Y; - - DFF_P dff_p_inst (.C(C), .D(A), .Q(Y)); - GAL_OUTPUT gal_output_inst (.A(Y)); -endmodule - -module REG_OUT_N (C, A, Y); - input C, A; - output Y; - - NDFF_P dff_p_inst (.C(C), .D(A), .Q(Y)); - GAL_OUTPUT gal_output_inst (.A(X)); -endmodule diff --git a/extractions/tristate.v b/extractions/tristate.v new file mode 100644 index 0000000..93a5b1e --- /dev/null +++ b/extractions/tristate.v @@ -0,0 +1,29 @@ +module TRI_DFF_P (C, E, D, Q); + input C, E, D; + inout Q; + + wire X; + + GAL_TRI gal_tri_inst (.A(X), .E(E), .Y(Q)); + DFF_P dff_inst (.D(D), .C(C), .Q(X)); +endmodule + +module TRI_NDFF_P (C, E, D, Q); + input C, E, D; + inout Q; + + wire X; + + GAL_TRI gal_tri_inst (.A(X), .E(E), .Y(Q)); + NDFF_P dff_inst (.D(D), .C(C), .Q(X)); +endmodule + +module GAL_TRI_N (C, E, D, Q); + input C, E, D; + inout Q; + + wire X; + + GAL_TRI gal_tri_inst (.A(X), .E(E), .Y(Q)); + $_NOT_ not_inst (.A(D), .Y(X)); +endmodule diff --git a/synth_gal.tcl b/synth_gal.tcl index 61951f4..130288d 100755 --- a/synth_gal.tcl +++ b/synth_gal.tcl @@ -35,9 +35,8 @@ tribuf synth design -save preop -# Map IO pins (and undo port removal for the output) -iopadmap -bits -inpad GAL_INPUT Y:A -toutpad GAL_OUTPUT E:A:Y -outpad GAL_OUTPUT A -expose */t:GAL_OUTPUT "%x:+\[A\]" */t:GAL_OUTPUT %d +# Map inputs and tristate pins +iopadmap -bits -inpad GAL_INPUT Y:A -toutpad GAL_TRI E:A:Y -tinoutpad GAL_TRI E:Y:A ## DFF/SOP mapping dfflibmap -liberty techmaps/gal_dff.lib @@ -71,13 +70,21 @@ techmap -max_iter 1 -map techmaps/trivial_sop.v # Sequential OLMC extract -constports -map extractions/ndff.v -extract -constports -map extractions/olmc.v +extract -constports -map extractions/tristate.v techmap -map techmaps/olmc_seq.v +# Make 1SOPs for combinational tristates +techmap -max_iter 1 -map techmaps/one_sop.v */t:GAL_TRI "%x:+\[E\]" */t:GAL_TRI %d %ci1 */t:GAL_SOP %i +techmap -max_iter 1 -map techmaps/one_sop.v */t:GAL_TRI_N "%x:+\[E\]" */t:GAL_TRI_N %d %ci1 */t:GAL_SOP %i +shell + # Add OLMC for internal GAL_SOPs #techmap -max_iter 1 -map techmaps/pla_olmc_int.v */t:GAL_OLMC %ci2 */t:GAL_SOP %i */t:GAL_SOP %D techmap -max_iter 1 -map techmaps/pla_olmc_int.v */t:GAL_SOP %co1 */w:* %i */t:GAL_SOP %ci1 */w:* %i %i %c %ci1 %D +# Add OLMC for internal GAL_SOPs attached to enable lines +techmap -max_iter 1 -map techmaps/pla_olmc_int.v */t:GAL_SOP %co1 */w:* %i */t:GAL_OLMC "%ci1:+\[E\]" */w:* %i %i %c %ci1 %D + # Combinational OLMC iopadmap -bits -outpad GAL_COMB_OUTPUT_P A:Y */t:GAL_SOP "%x:+\[Y\]" */t:GAL_SOP %d o:* %i techmap -map techmaps/olmc_comb.v @@ -111,7 +118,7 @@ ltp -noff design -load postop ## Print final stats and show graph -show -width -signed -enum +show -width -signed stat shell diff --git a/techmaps/olmc_comb.v b/techmaps/olmc_comb.v index 20fb2c9..3c31b59 100644 --- a/techmaps/olmc_comb.v +++ b/techmaps/olmc_comb.v @@ -1,6 +1,7 @@ (* techmap_celltype = "GAL_COMB_OUTPUT_P" *) module _80_GAL_COMB_OUTPUT_P (A, Y); - input A, Y; + input A; + output Y; generate GAL_OLMC #( @@ -17,7 +18,8 @@ endmodule (* techmap_celltype = "$_NOT_" *) module _80_NOT (A, Y); - input A, Y; + input A; + output Y; generate GAL_OLMC #( @@ -31,3 +33,39 @@ module _80_NOT (A, Y); ); endgenerate endmodule + +(* techmap_celltype = "GAL_TRI" *) +module _80_GAL_TRI (A, E, Y); + input A, E; + inout Y; + + generate + GAL_OLMC #( + .REGISTERED(1'b0), + .INVERTED(1'b0) + ) _TECHMAP_REPLACE_ ( + .C(1'bX), + .E(E), + .A(A), + .Y(Y) + ); + endgenerate +endmodule + +(* techmap_celltype = "GAL_TRI_N" *) +module _80_GAL_TRI (A, E, Y); + input A, E; + inout Y; + + generate + GAL_OLMC #( + .REGISTERED(1'b0), + .INVERTED(1'b1) + ) _TECHMAP_REPLACE_ ( + .C(1'bX), + .E(E), + .A(A), + .Y(Y) + ); + endgenerate +endmodule diff --git a/techmaps/olmc_seq.v b/techmaps/olmc_seq.v index d6a5b8c..03b5cb1 100644 --- a/techmaps/olmc_seq.v +++ b/techmaps/olmc_seq.v @@ -1,21 +1,3 @@ -(* techmap_celltype = "REG_OUT_P" *) -module _80_REG_OUT_P (C, A, Y); - input C, A; - output Y; - - generate - GAL_OLMC #( - .REGISTERED(1'b1), - .INVERTED(1'b0) - ) _TECHMAP_REPLACE_ ( - .C(C), - .E(1'b1), - .A(A), - .Y(Y) - ); - endgenerate -endmodule - (* techmap_celltype = "DFF_P" *) module _80_DFF_P (C, D, Q); input C, D; @@ -34,24 +16,6 @@ module _80_DFF_P (C, D, Q); endgenerate endmodule -(* techmap_celltype = "REG_OUT_N" *) -module _81_REG_OUT_N (C, A, Y); - input C, A; - output Y; - - generate - GAL_OLMC #( - .REGISTERED(1'b1), - .INVERTED(1'b1) - ) _TECHMAP_REPLACE_ ( - .C(C), - .E(1'b1), - .A(A), - .Y(Y) - ); - endgenerate -endmodule - (* techmap_celltype = "NDFF_P" *) module _81_NDFF_P (C, D, Q); input C, D; @@ -70,9 +34,38 @@ module _81_NDFF_P (C, D, Q); endgenerate endmodule -(* techmap_celltype = "GAL_OUTPUT" *) -module _82_GAL_OUTPUT (A); - input A; +(* techmap_celltype = "TRI_DFF_P" *) +module _80_TRI_DFF_P (C, E, D, Q); + input C, E, D; + inout Q; - // Delete + generate + GAL_OLMC #( + .REGISTERED(1'b1), + .INVERTED(1'b0) + ) _TECHMAP_REPLACE_ ( + .C(C), + .E(E), + .A(D), + .Y(Q) + ); + endgenerate +endmodule + +(* techmap_celltype = "TRI_NDFF_P" *) +module _81_TRI_NDFF_P (C, E, D, Q); + input C, E, D; + inout Q; + + generate + GAL_OLMC #( + .REGISTERED(1'b1), + .INVERTED(1'b1) + ) _TECHMAP_REPLACE_ ( + .C(C), + .E(E), + .A(D), + .Y(Q) + ); + endgenerate endmodule diff --git a/techmaps/one_sop.v b/techmaps/one_sop.v new file mode 100644 index 0000000..49b8454 --- /dev/null +++ b/techmaps/one_sop.v @@ -0,0 +1,34 @@ +// Convert GAL_SOPs with only 1 product into a "1SOP" +// Intended for the enable product + +(* techmap_celltype = "GAL_SOP" *) +module _80_GAL_SOP (A, Y); + parameter WIDTH = 0; + parameter DEPTH = 0; + parameter TABLE = 0; + + input [WIDTH-1:0] A; + output reg Y; + + generate + if (DEPTH == 1) begin + GAL_1SOP #( + .WIDTH(WIDTH), + .DEPTH(DEPTH), + .TABLE(TABLE) + ) _TECHMAP_REPLACE_ ( + .A(A), + .Y(Y) + ); + end else begin // No-op + GAL_SOP #( + .WIDTH(WIDTH), + .DEPTH(DEPTH), + .TABLE(TABLE) + ) _TECHMAP_REPLACE_ ( + .A(A), + .Y(Y) + ); + end + endgenerate +endmodule diff --git a/techmaps/tristate.v b/techmaps/tristate.v new file mode 100644 index 0000000..48bc4c9 --- /dev/null +++ b/techmaps/tristate.v @@ -0,0 +1,17 @@ +module GAL_INOUT_TRI(A, E, I, Y); + input A, E; + output I; + inout Y; + + generate + GAL_OLMC #( + REGISTERED = 0, + INVERTED = 0 + ) _TECHMAP_REPLACE_ ( + .A(A), + .C(1'bX), + .E(E), + .Y(E ? Y : I); + ); + endgenerate +endmodule diff --git a/testcases/inout_tristate.v b/testcases/inout_tristate.v new file mode 100644 index 0000000..abe913b --- /dev/null +++ b/testcases/inout_tristate.v @@ -0,0 +1,10 @@ +module inout_tristate ( + input a, b, c, + inout y, + output z +); + +assign y = c && b ? a && b : 1'bz; +assign z = c ? a || b : y; + +endmodule diff --git a/testcases/reg_tristate.v b/testcases/reg_tristate.v new file mode 100644 index 0000000..264ec88 --- /dev/null +++ b/testcases/reg_tristate.v @@ -0,0 +1,14 @@ +module reg_tristate ( + input clk, + input a, b, c, + output y +); + +reg x; + +assign y = c && b ? x : 1'bz; + +always @ (posedge clk) + x <= a && b; + +endmodule