raw
fg-genesis              1 ///////////////////////////////////////////////////////////////////////////
fg-genesis 2 // FUCKGOATS CPLD circuit. V.3K (December 2016.)
fg-genesis 3 //
fg-genesis 4 // This was written for an XC9572XL. It SHOULD work on any gate array of
fg-genesis 5 // equal or greater size, but no such assurance is given.
fg-genesis 6 // It SHOULD also work quite well in the form of an ASIC, or in TTL, or
fg-genesis 7 // using any other reasonably-fast logic element.
fg-genesis 8 //
fg-genesis 9 // (C) 2016 No Such lAbs.
fg-genesis 10 //
fg-genesis 11 // You do not have, nor can you ever acquire the right to use, copy or
fg-genesis 12 // distribute this software ; Should you use this software for any purpose,
fg-genesis 13 // or copy and distribute it to anyone or in any manner, you are breaking
fg-genesis 14 // the laws of whatever soi-disant jurisdiction, and you promise to
fg-genesis 15 // continue doing so for the indefinite future. In any case, please
fg-genesis 16 // always : read and understand any software ; verify any PGP signatures
fg-genesis 17 // that you use - for any purpose.
fg-genesis 18 ///////////////////////////////////////////////////////////////////////////
fg-genesis 19
fg-genesis 20 ///////////////////////////////////////////////////////////////////////////
fg-genesis 21 // Knobs.
fg-genesis 22 ///////////////////////////////////////////////////////////////////////////
fg-genesis 23 // BITS of analogue input used to make each BYTE of accum output.
fg-genesis 24 // You MAY want to change if you were to use another type of analogue RNG,
fg-genesis 25 // particularly one having a different spectrum from the 'TW' board.
fg-genesis 26 `define FOLD_RSIZE 4 // size of counter register
fg-genesis 27 `define FOLD 4'd15 // bit count
fg-genesis 28 ///////////////////////////////////////////////////////////////////////////
fg-genesis 29
fg-genesis 30
fg-genesis 31 // div128, for UART's 115200b on 14.7456MHz crystal.
fg-genesis 32 // We also use it as slow clock for the watchdog.
fg-genesis 33 module baudgen(clk, clkout);
fg-genesis 34 input clk;
fg-genesis 35 output clkout;
fg-genesis 36
fg-genesis 37 reg [6:0] counter = 0;
fg-genesis 38 wire clkout;
fg-genesis 39
fg-genesis 40 always @(posedge clk)
fg-genesis 41 begin
fg-genesis 42 counter <= counter + 1;
fg-genesis 43 end
fg-genesis 44 assign clkout = (counter == 7'b1111111);
fg-genesis 45 endmodule
fg-genesis 46
fg-genesis 47
fg-genesis 48 // A very simple TX-only UART. 'No user serviceable parts inside.'
fg-genesis 49 // No async reset, because nothing good can come of aborting mid-byte.
fg-genesis 50 module ser_tx(clk, baud_clk, fire, txbyte, tx, busy);
fg-genesis 51 input clk, baud_clk, fire;
fg-genesis 52 input [7:0] txbyte;
fg-genesis 53 output tx, busy;
fg-genesis 54 wire busy;
fg-genesis 55
fg-genesis 56 // Transmitter state machine
fg-genesis 57 reg [3:0] state = 0;
fg-genesis 58 wire tx_ready = (state == 0);
fg-genesis 59 assign busy = ~tx_ready;
fg-genesis 60
fg-genesis 61 wire [7:0] txbyteD = txbyte;
fg-genesis 62
fg-genesis 63 always @(posedge clk)
fg-genesis 64 case(state)
fg-genesis 65 4'b0000: if(fire) state <= 4'b0001;
fg-genesis 66 4'b0001: if(baud_clk) state <= 4'b0100;
fg-genesis 67 4'b0100: if(baud_clk) state <= 4'b1000; // start
fg-genesis 68 4'b1000: if(baud_clk) state <= 4'b1001; // bit 0
fg-genesis 69 4'b1001: if(baud_clk) state <= 4'b1010; // bit 1
fg-genesis 70 4'b1010: if(baud_clk) state <= 4'b1011; // bit 2
fg-genesis 71 4'b1011: if(baud_clk) state <= 4'b1100; // bit 3
fg-genesis 72 4'b1100: if(baud_clk) state <= 4'b1101; // bit 4
fg-genesis 73 4'b1101: if(baud_clk) state <= 4'b1110; // bit 5
fg-genesis 74 4'b1110: if(baud_clk) state <= 4'b1111; // bit 6
fg-genesis 75 4'b1111: if(baud_clk) state <= 4'b0010; // bit 7
fg-genesis 76 4'b0010: if(baud_clk) state <= 4'b0000; // stop1
fg-genesis 77 4'b0011: if(baud_clk) state <= 4'b0000; // stop2 (off)
fg-genesis 78 default: if(baud_clk) state <= 4'b0000;
fg-genesis 79 endcase
fg-genesis 80
fg-genesis 81 reg muxbit;
fg-genesis 82 always @(*)
fg-genesis 83 case(state[2:0])
fg-genesis 84 3'd0: muxbit <= txbyteD[0];
fg-genesis 85 3'd1: muxbit <= txbyteD[1];
fg-genesis 86 3'd2: muxbit <= txbyteD[2];
fg-genesis 87 3'd3: muxbit <= txbyteD[3];
fg-genesis 88 3'd4: muxbit <= txbyteD[4];
fg-genesis 89 3'd5: muxbit <= txbyteD[5];
fg-genesis 90 3'd6: muxbit <= txbyteD[6];
fg-genesis 91 3'd7: muxbit <= txbyteD[7];
fg-genesis 92 endcase
fg-genesis 93
fg-genesis 94 reg tx;
fg-genesis 95 always @(posedge clk)
fg-genesis 96 tx <= (state<4) | (state[3] & muxbit);
fg-genesis 97 endmodule
fg-genesis 98
fg-genesis 99
fg-genesis 100 // One way to gather entropy from absolute pulse widths.
fg-genesis 101 // This was not feasible in v.10K (it could not rely on synced clk.)
fg-genesis 102 module eater(clk, nres, in, valid, out);
fg-genesis 103 input clk, nres, in;
fg-genesis 104 output valid, out;
fg-genesis 105
fg-genesis 106 reg [3:0] q;
fg-genesis 107 reg out;
fg-genesis 108 reg s;
fg-genesis 109
fg-genesis 110 always @(posedge clk or negedge nres)
fg-genesis 111 if (~nres)
fg-genesis 112 begin
fg-genesis 113 s <= 0;
fg-genesis 114 end
fg-genesis 115 else
fg-genesis 116 begin
fg-genesis 117 s <= in;
fg-genesis 118 end
fg-genesis 119
fg-genesis 120 wire pulse = s ^ in; // either rise or fall of input
fg-genesis 121
fg-genesis 122 always @(posedge clk or negedge nres)
fg-genesis 123 if (~nres)
fg-genesis 124 begin
fg-genesis 125 q <= 0;
fg-genesis 126 out <= 0;
fg-genesis 127 end
fg-genesis 128 else
fg-genesis 129 begin
fg-genesis 130 out <= q[3] ^ q[2] ^ q[1] ^ q[0];
fg-genesis 131 q <= pulse ? 0 : q + 1;
fg-genesis 132 end
fg-genesis 133
fg-genesis 134 assign valid = pulse;
fg-genesis 135 endmodule
fg-genesis 136 // NOTE that if you are doing a yoke test with two units and one set
fg-genesis 137 // of analogue RNGs, you must buffer the latter with a latch clocked
fg-genesis 138 // from the common clock, so that they obey the hold time constraint
fg-genesis 139 // of the CPLD's input buffer. Without this, operation will ~still~
fg-genesis 140 // be repeatable between the yoked units, but ~with errors~.
fg-genesis 141
fg-genesis 142
fg-genesis 143 // Von Neumann's 'fair coin' algorithm.
fg-genesis 144 module debias(clk, res, fire, in, valid, out);
fg-genesis 145 input clk, res, fire, in;
fg-genesis 146 output valid, out;
fg-genesis 147
fg-genesis 148 reg p, q;
fg-genesis 149 reg [1:0] state;
fg-genesis 150 wire valid;
fg-genesis 151
fg-genesis 152 always @(posedge clk or negedge res)
fg-genesis 153 if (~res)
fg-genesis 154 begin
fg-genesis 155 state <= 0;
fg-genesis 156 p <= 0;
fg-genesis 157 q <= 0;
fg-genesis 158 end
fg-genesis 159 else
fg-genesis 160 begin
fg-genesis 161 case(state)
fg-genesis 162 2'd0:
fg-genesis 163 begin
fg-genesis 164 p <= in;
fg-genesis 165 state <= fire ? 2'd1 : 2'd0;
fg-genesis 166 end
fg-genesis 167 2'd1:
fg-genesis 168 begin
fg-genesis 169 q <= in;
fg-genesis 170 state <= fire ? 2'd2 : 2'd1;
fg-genesis 171 end
fg-genesis 172 2'd2:
fg-genesis 173 begin
fg-genesis 174 state <= 2'd0;
fg-genesis 175 end
fg-genesis 176 2'd3: // unused
fg-genesis 177 begin
fg-genesis 178 state <= 2'd0;
fg-genesis 179 end
fg-genesis 180 endcase
fg-genesis 181 end
fg-genesis 182
fg-genesis 183 assign valid = (p ^ q) & (state == 2'd2);
fg-genesis 184 assign out = p;
fg-genesis 185 endmodule
fg-genesis 186
fg-genesis 187
fg-genesis 188 // Byte Accumulator.
fg-genesis 189 module accum(clk, nres, fire, in, roll, rdy);
fg-genesis 190 parameter fold = 8; // bits per shot
fg-genesis 191 parameter count_bits = 4;
fg-genesis 192
fg-genesis 193 input clk, in, nres, fire;
fg-genesis 194 output rdy;
fg-genesis 195 output [7:0] roll;
fg-genesis 196
fg-genesis 197 reg [7:0] roll;
fg-genesis 198 reg [count_bits-1:0] bit_count;
fg-genesis 199 reg rdy;
fg-genesis 200
fg-genesis 201 always @(posedge clk or negedge nres)
fg-genesis 202 begin
fg-genesis 203 if (~nres) // async reset
fg-genesis 204 begin
fg-genesis 205 bit_count <= 0;
fg-genesis 206 roll <= 0;
fg-genesis 207 rdy <= 0;
fg-genesis 208 end
fg-genesis 209 else
fg-genesis 210 if (fire)
fg-genesis 211 begin
fg-genesis 212 roll[bit_count[2:0]] <= roll[bit_count[2:0]] ^ in;
fg-genesis 213 bit_count <= bit_count + 1;
fg-genesis 214 if (bit_count == fold) rdy <= 1; // raise ready flag
fg-genesis 215 end
fg-genesis 216 end
fg-genesis 217 endmodule
fg-genesis 218
fg-genesis 219
fg-genesis 220 // Watchdog. Counter, stops advancing at max until reset.
fg-genesis 221 module dog(clk, nres, run, alarm);
fg-genesis 222 input clk, nres, run;
fg-genesis 223 output alarm;
fg-genesis 224
fg-genesis 225 reg [5:0] count;
fg-genesis 226
fg-genesis 227 assign alarm = (count == 6'b111111);
fg-genesis 228
fg-genesis 229 always @(posedge clk or negedge nres)
fg-genesis 230 begin
fg-genesis 231 if (~nres) // async reset
fg-genesis 232 begin
fg-genesis 233 count <= 0;
fg-genesis 234 end
fg-genesis 235 else
fg-genesis 236 if (run & ~alarm)
fg-genesis 237 begin
fg-genesis 238 count <= count + 1;
fg-genesis 239 end
fg-genesis 240 end
fg-genesis 241 endmodule
fg-genesis 242
fg-genesis 243
fg-genesis 244 // Werker.
fg-genesis 245 module fg(input wire xtal, // on-board clock, from 14.7456MHz resonator
fg-genesis 246 inout wire clk, // clock output (master) or input (slave)
fg-genesis 247 input wire IN_A, // 'bottom' analogue RNG input, pulled high
fg-genesis 248 input wire IN_B, // 'top' analogue RNG input, pulled high
fg-genesis 249 output wire ser_tx, // output of UART, to TTL converter
fg-genesis 250 output wire SAD // red lamp
fg-genesis 251 );
fg-genesis 252
fg-genesis 253 ///////////////////////////////////////////////////////////////////////////
fg-genesis 254 // Serial UART
fg-genesis 255 ///////////////////////////////////////////////////////////////////////////
fg-genesis 256
fg-genesis 257 wire tx;
fg-genesis 258 wire fire;
fg-genesis 259 wire busy;
fg-genesis 260 wire baud_clk;
fg-genesis 261 reg [7:0] txbyte;
fg-genesis 262
fg-genesis 263 // baud clock generator
fg-genesis 264 baudgen bg(clk, baud_clk);
fg-genesis 265
fg-genesis 266 // UART.
fg-genesis 267 ser_tx sender(clk, baud_clk, fire, txbyte, tx, busy);
fg-genesis 268
fg-genesis 269 ///////////////////////////////////////////////////////////////////////////
fg-genesis 270 // Master/Slave toggle, for clock-synchronized slave yoke tests.
fg-genesis 271 // Yoke two units by connecting the CLK ('RESET' on v1 pcb) pins together.
fg-genesis 272 // The first board powered up will become the master.
fg-genesis 273 // Slave's red lamp will stay lit, and his clock is inhibited, uses master
fg-genesis 274 ///////////////////////////////////////////////////////////////////////////
fg-genesis 275 reg [2:0] boot_state = 0;
fg-genesis 276
fg-genesis 277 // If I master, I output ~my~ clock; otherwise - I slave, wait for a clock:
fg-genesis 278 wire am_master = (boot_state == 3'd6);
fg-genesis 279 assign clk = am_master ? xtal : 1'bz; // this pin is pulled high
fg-genesis 280
fg-genesis 281 // Breath of Life
fg-genesis 282 always @(posedge xtal) // must use on-board oscillator, for obvious reasons
fg-genesis 283 begin
fg-genesis 284 case(boot_state)
fg-genesis 285 default:
fg-genesis 286 begin
fg-genesis 287 boot_state <= clk ? boot_state + 1 : 3'd7;
fg-genesis 288 end
fg-genesis 289 3'd6: // I am a master, for life! (until powerdown)
fg-genesis 290 begin
fg-genesis 291 boot_state <= 3'd6;
fg-genesis 292 end
fg-genesis 293 3'd7: // I am a slave, for life! (until powerdown)
fg-genesis 294 begin
fg-genesis 295 boot_state <= 3'd7;
fg-genesis 296 end
fg-genesis 297 endcase
fg-genesis 298 end
fg-genesis 299
fg-genesis 300 // we want to hold reset for a short while on bootup
fg-genesis 301 reg nreset = 0;
fg-genesis 302
fg-genesis 303 always @(posedge clk) // use the active clock, ~when we get one~
fg-genesis 304 begin
fg-genesis 305 if ((~IN_A) & (~IN_B) & baud_clk) // stay in reset until both rng work
fg-genesis 306 begin // and until first baud clock pulse
fg-genesis 307 nreset <= 1'd1;
fg-genesis 308 end
fg-genesis 309 end
fg-genesis 310
fg-genesis 311 // We hold ser_tx low on reset, this way it is easy to see when finished.
fg-genesis 312 assign ser_tx = tx & nreset;
fg-genesis 313
fg-genesis 314 ///////////////////////////////////////////////////////////////////////////
fg-genesis 315
fg-genesis 316 ///////////////////////////////////////////////////////////////////////////
fg-genesis 317 // If this device were to grind to a halt, wouldn't you like to know?
fg-genesis 318 ///////////////////////////////////////////////////////////////////////////
fg-genesis 319 wire dog_alarm;
fg-genesis 320 wire dog_run;
fg-genesis 321 wire dog_reset;
fg-genesis 322
fg-genesis 323 dog sad_dog(clk,
fg-genesis 324 dog_reset & nreset, // watchdog reset (if either dips low)
fg-genesis 325 dog_run, // watchdog enable-advance
fg-genesis 326 dog_alarm); // watchdog alarm, tied to 'SAD' lamp
fg-genesis 327 ///////////////////////////////////////////////////////////////////////////
fg-genesis 328
fg-genesis 329 ///////////////////////////////////////////////////////////////////////////
fg-genesis 330 // RNG
fg-genesis 331 ///////////////////////////////////////////////////////////////////////////
fg-genesis 332 wire eater_a_valid;
fg-genesis 333 wire eater_a_out;
fg-genesis 334 eater e_a(clk, nreset, IN_A, eater_a_valid, eater_a_out);
fg-genesis 335
fg-genesis 336 wire eater_b_valid;
fg-genesis 337 wire eater_b_out;
fg-genesis 338 eater e_b(clk, nreset, IN_B, eater_b_valid, eater_b_out);
fg-genesis 339
fg-genesis 340 wire valid_a;
fg-genesis 341 wire outbit_a;
fg-genesis 342
fg-genesis 343 debias dbias_a(clk,
fg-genesis 344 nreset,
fg-genesis 345 eater_a_valid,
fg-genesis 346 eater_a_out,
fg-genesis 347 valid_a,
fg-genesis 348 outbit_a);
fg-genesis 349
fg-genesis 350 wire valid_b;
fg-genesis 351 wire outbit_b;
fg-genesis 352
fg-genesis 353 debias dbias_b(clk,
fg-genesis 354 nreset,
fg-genesis 355 eater_b_valid,
fg-genesis 356 eater_b_out,
fg-genesis 357 valid_b,
fg-genesis 358 outbit_b);
fg-genesis 359
fg-genesis 360 // per xor lemma:
fg-genesis 361 wire valid = valid_a | valid_b;
fg-genesis 362 wire outbit = outbit_a ^ outbit_b;
fg-genesis 363
fg-genesis 364 wire acc_res; // reset accum (active low)
fg-genesis 365 wire acc_rdy; // accum has byte
fg-genesis 366 wire [7:0] acc_byte; // output of accumulator
fg-genesis 367
fg-genesis 368 accum #(.fold(`FOLD),
fg-genesis 369 .count_bits(`FOLD_RSIZE)) acc_a(clk,
fg-genesis 370 acc_res & nreset, // if either low
fg-genesis 371 valid,
fg-genesis 372 outbit,
fg-genesis 373 acc_byte,
fg-genesis 374 acc_rdy);
fg-genesis 375
fg-genesis 376 ///////////////////////////////////////////////////////////////////////////
fg-genesis 377
fg-genesis 378 // device cycles forever through four phases
fg-genesis 379 reg [1:0] state;
fg-genesis 380
fg-genesis 381 always @(posedge clk or negedge nreset)
fg-genesis 382 if (~nreset)
fg-genesis 383 begin
fg-genesis 384 state <= 0;
fg-genesis 385 txbyte <= 0;
fg-genesis 386 end
fg-genesis 387 else
fg-genesis 388 begin
fg-genesis 389 case(state)
fg-genesis 390 2'd0: // ground state
fg-genesis 391 begin
fg-genesis 392 txbyte <= 0; // clear tx buffer
fg-genesis 393 state <= 2'd1; // next
fg-genesis 394 end
fg-genesis 395 2'd1:
fg-genesis 396 begin // wait for 'a' accum
fg-genesis 397 if (acc_rdy)
fg-genesis 398 begin
fg-genesis 399 txbyte <= acc_byte;
fg-genesis 400 state <= 2'd2; // next
fg-genesis 401 end
fg-genesis 402 else
fg-genesis 403 state <= 2'd1; // wait
fg-genesis 404 end
fg-genesis 405 2'd2:
fg-genesis 406 begin // clear 'a'; fire tx
fg-genesis 407 state <= 2'd3; // next
fg-genesis 408 end
fg-genesis 409 2'd3:
fg-genesis 410 begin // wait to end of tx
fg-genesis 411 state <= (~busy) ? 2'd0 : 2'd3; // wait for UART
fg-genesis 412 end
fg-genesis 413 endcase
fg-genesis 414 end
fg-genesis 415
fg-genesis 416 assign fire = (state == 2'd2); // txbyte is ready, so fire the UART
fg-genesis 417 assign acc_res = ~(fire); // zap acc_byte (active low)
fg-genesis 418
fg-genesis 419 // advance dogometer at the baud clock rate
fg-genesis 420 assign dog_run = baud_clk & (state == 2'd1);
fg-genesis 421
fg-genesis 422 assign dog_reset = acc_res; // reset dogometer we got a byte
fg-genesis 423
fg-genesis 424 // Red 'Sadness' lamp.
fg-genesis 425 // If STEADILY LIT, check ALL connections: the device is halted and is
fg-genesis 426 // doing NO USEFUL WORK at all!
fg-genesis 427 // Re-seat analogue RNG boards, check their power supplies (if you have,
fg-genesis 428 // e.g., a custom isolation system.) Otherwise - one or both analogue
fg-genesis 429 // RNG units may need replacement.
fg-genesis 430 assign SAD = dog_alarm | ~am_master | (~nreset);
fg-genesis 431 // Red lamp will also light if the board is placed into the slave
fg-genesis 432 // state (for verification) using the external clock
fg-genesis 433 // (marked RESET on early board revs) pin; and when in RESET state.
fg-genesis 434 endmodule
fg-genesis 435
fg-genesis 436 ///////////////////////////////////////////////////////////////////////////
fg-genesis 437 ///////////////////////////////////////////////////////////////////////////