// The four D flip-flops (DFFs) in a Cyclone V/10GX Adaptive Logic Module (ALM) // act as one-bit memory cells that can be placed very flexibly (wherever there's // an ALM); each flop is represented by a MISTRAL_FF cell. // // The flops in these chips are rather flexible in some ways, but in practice // quite crippled by FPGA standards. // // What the flops can do // --------------------- // The core flop acts as a single-bit memory that initialises to zero at chip // reset. It takes in data on the rising edge of CLK if ENA is high, // and outputs it to Q. The ENA (clock enable) pin can therefore be used to // capture the input only if a condition is true. // // The data itself is zero if SCLR (synchronous clear) is high, else it comes // from SDATA (synchronous data) if SLOAD (synchronous load) is high, or DATAIN // if SLOAD is low. // // If ACLR (asynchronous clear) is low then Q is forced to zero, regardless of // the synchronous inputs or CLK edge. This is most often used for an FPGA-wide // power-on reset. // // An asynchronous set that sets Q to one can be emulated by inverting the input // and output of the flop, resulting in ACLR forcing Q to zero, which then gets // inverted to produce one. Likewise, logic can operate on the falling edge of // CLK if CLK is inverted before being passed as an input. // // What the flops *can't* do // ------------------------- // The trickiest part of the above capabilities is the lack of configurable // initialisation state. For example, it isn't possible to implement a flop with // asynchronous clear that initialises to one, because the hardware initialises // to zero. Likewise, you can't emulate a flop with asynchronous set that // initialises to zero, because the inverters mean the flop initialises to one. // // If the input design requires one of these cells (which appears to be rare // in practice) then synth_intel_alm will fail to synthesize the design where // other Yosys synthesis scripts might succeed. // // This stands in notable contrast to e.g. Xilinx flip-flops, which have // configurable initialisation state and native synchronous/asynchronous // set/clear (although not at the same time), which means they can generally // implement a much wider variety of logic. // DATAIN: synchronous data input // CLK: clock input (positive edge) // ACLR: asynchronous clear (negative-true) // ENA: clock-enable // SCLR: synchronous clear // SLOAD: synchronous load // SDATA: synchronous load data // // Q: data output // // Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements. (* abc9_box, lib_whitebox *) module MISTRAL_FF( input DATAIN, (* clkbuf_sink *) input CLK, input ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q ); `ifdef cyclonev specify if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 731; if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 890; if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 618; $setup(DATAIN, posedge CLK, /* -196 */ 0); $setup(ENA, posedge CLK, /* -196 */ 0); $setup(SCLR, posedge CLK, /* -196 */ 0); $setup(SLOAD, posedge CLK, /* -196 */ 0); $setup(SDATA, posedge CLK, /* -196 */ 0); if (ACLR === 1'b0) (ACLR => Q) = 282; endspecify `endif `ifdef arriav specify if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470; if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633; if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439; $setup(DATAIN, posedge CLK, /* -170 */ 0); $setup(ENA, posedge CLK, /* -170 */ 0); $setup(SCLR, posedge CLK, /* -170 */ 0); $setup(SLOAD, posedge CLK, /* -170 */ 0); $setup(SDATA, posedge CLK, /* -170 */ 0); if (ACLR === 1'b0) (ACLR => Q) = 215; endspecify `endif `ifdef cyclone10gx specify // TODO (long-term): investigate these numbers. // It seems relying on the Quartus Timing Analyzer was not the best idea; it's too fiddly. if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 219; if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 219; if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 219; $setup(DATAIN, posedge CLK, 268); $setup(ENA, posedge CLK, 268); $setup(SCLR, posedge CLK, 268); $setup(SLOAD, posedge CLK, 268); $setup(SDATA, posedge CLK, 268); if (ACLR === 1'b0) (ACLR => Q) = 0; endspecify `endif initial begin // Altera flops initialise to zero. Q = 0; end always @(posedge CLK, negedge ACLR) begin // Asynchronous clear if (!ACLR) Q <= 0; // Clock-enable else if (ENA) begin // Synchronous clear if (SCLR) Q <= 0; // Synchronous load else if (SLOAD) Q <= SDATA; else Q <= DATAIN; end end endmodule > 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187