From 13d0ff4a5fb8caac3a9d3619921a3c4d315fd8f3 Mon Sep 17 00:00:00 2001 From: "R. Ou" Date: Mon, 17 Feb 2020 03:07:16 -0800 Subject: [PATCH] coolrunner2: Use extract_counter to optimize counters This tends to make much more efficient pterm usage compared to just throwing the problem at ABC --- techlibs/coolrunner2/Makefile.inc | 1 + techlibs/coolrunner2/cells_counter_map.v | 161 ++++++++++++++++++++++ techlibs/coolrunner2/synth_coolrunner2.cc | 3 + 3 files changed, 165 insertions(+) create mode 100644 techlibs/coolrunner2/cells_counter_map.v diff --git a/techlibs/coolrunner2/Makefile.inc b/techlibs/coolrunner2/Makefile.inc index d62c9960c..c879e95cd 100644 --- a/techlibs/coolrunner2/Makefile.inc +++ b/techlibs/coolrunner2/Makefile.inc @@ -4,5 +4,6 @@ OBJS += techlibs/coolrunner2/coolrunner2_sop.o $(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_latch.v)) $(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_sim.v)) +$(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/cells_counter_map.v)) $(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/tff_extract.v)) $(eval $(call add_share_file,share/coolrunner2,techlibs/coolrunner2/xc2_dff.lib)) diff --git a/techlibs/coolrunner2/cells_counter_map.v b/techlibs/coolrunner2/cells_counter_map.v new file mode 100644 index 000000000..b474fa522 --- /dev/null +++ b/techlibs/coolrunner2/cells_counter_map.v @@ -0,0 +1,161 @@ +module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); + + input wire CE; + input wire CLK; + output wire OUT; + output wire[WIDTH-1:0] POUT; + input wire RST; + input wire UP; + + parameter COUNT_TO = 1; + parameter RESET_MODE = "RISING"; + parameter RESET_TO_MAX = 0; + parameter HAS_POUT = 0; + parameter HAS_CE = 0; + parameter WIDTH = 8; + parameter DIRECTION = "DOWN"; + + if (DIRECTION == "UP") begin + if (WIDTH < 2) begin + initial begin + $display("ERROR: \$__COUNT_ must be at least 2 bits wide (bug in extract_counter pass?)."); + $finish; + end + end + + // FIXME: Max width? + + assign OUT = POUT == COUNT_TO; + + if (HAS_CE) begin + genvar i; + for (i = 0; i < WIDTH; i++) begin: countbits + // each bit = (cur & !reset) ^ (all prev & !reset) + wire xor_to_mc_bitn; + FDCP #( + .INIT(0) + ) bitn_ff ( + .C(CLK), + .CLR(0), + .D(xor_to_mc_bitn), + .PRE(0), + .Q(POUT[i]) + ); + wire orterm_to_xor_bitn; + wire pterm0_to_or_bitn; + wire pterm1_to_or_bitn; + MACROCELL_XOR #( + .INVERT_OUT(0) + ) bitn_xor ( + .IN_ORTERM(orterm_to_xor_bitn), + .IN_PTC(pterm1_to_or_bitn), + .OUT(xor_to_mc_bitn) + ); + ORTERM #( + .WIDTH(1) + ) bitn_or ( + .IN(pterm0_to_or_bitn), + .OUT(orterm_to_xor_bitn) + ); + ANDTERM #( + .COMP_INP(1), + .TRUE_INP(1) + ) bitn_pterm0 ( + .IN(POUT[i]), + .IN_B(OUT), + .OUT(pterm0_to_or_bitn) + ); + ANDTERM #( + .COMP_INP(1), + .TRUE_INP(i + 1) + ) bitn_pterm1 ( + .IN({POUT[i-1:0], CE}), + .IN_B(OUT), + .OUT(pterm1_to_or_bitn) + ); + end + end else begin + // Bit0 is special; toggle unless reset + // cur reset out + // 0 0 1 + // 0 1 0 + // 1 0 0 + // 1 1 0 + wire xor_to_mc_bit0; + FDCP #( + .INIT(0) + ) bit0_ff ( + .C(CLK), + .CLR(0), + .D(xor_to_mc_bit0), + .PRE(0), + .Q(POUT[0]) + ); + wire pterm_to_xor_bit0; + MACROCELL_XOR #( + .INVERT_OUT(0) + ) bit0_xor ( + .IN_PTC(pterm_to_xor_bit0), + .OUT(xor_to_mc_bit0) + ); + ANDTERM #( + .COMP_INP(2), + .TRUE_INP(0) + ) bit0_pterm ( + .IN(), + .IN_B({POUT[0], OUT}), + .OUT(pterm_to_xor_bit0) + ); + + genvar i; + for (i = 1; i < WIDTH; i++) begin: countbits + // each bit = (cur & !reset) ^ (all prev & !reset) + wire xor_to_mc_bitn; + FDCP #( + .INIT(0) + ) bitn_ff ( + .C(CLK), + .CLR(0), + .D(xor_to_mc_bitn), + .PRE(0), + .Q(POUT[i]) + ); + wire orterm_to_xor_bitn; + wire pterm0_to_or_bitn; + wire pterm1_to_or_bitn; + MACROCELL_XOR #( + .INVERT_OUT(0) + ) bitn_xor ( + .IN_ORTERM(orterm_to_xor_bitn), + .IN_PTC(pterm1_to_or_bitn), + .OUT(xor_to_mc_bitn) + ); + ORTERM #( + .WIDTH(1) + ) bitn_or ( + .IN(pterm0_to_or_bitn), + .OUT(orterm_to_xor_bitn) + ); + ANDTERM #( + .COMP_INP(1), + .TRUE_INP(1) + ) bitn_pterm0 ( + .IN(POUT[i]), + .IN_B(OUT), + .OUT(pterm0_to_or_bitn) + ); + ANDTERM #( + .COMP_INP(1), + .TRUE_INP(i) + ) bitn_pterm1 ( + .IN(POUT[i-1:0]), + .IN_B(OUT), + .OUT(pterm1_to_or_bitn) + ); + end + end + end + + // FIXME: down counters + +endmodule diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc index 3bac8623d..fa9105e34 100644 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ b/techlibs/coolrunner2/synth_coolrunner2.cc @@ -143,6 +143,9 @@ struct SynthCoolrunner2Pass : public ScriptPass if (check_label("fine")) { + run("extract_counter -dir up -allow_arst no"); + run("techmap -map +/coolrunner2/cells_counter_map.v"); + run("clean"); run("opt -fast -full"); run("techmap -map +/techmap.v -map +/coolrunner2/cells_latch.v"); run("opt -fast"); -- 2.30.2