## Introduction

Geocache puzzles are varied, and as befitting a game enjoyed by geeks many geocaches can only be found after you’ve solved a geeky puzzle. Some such puzzles involve electronics, and within this niche we find those which involve digital logic.

I’ve solved about half-a-dozen of them, and even set one: GC40ZBM1 near Cambridge in the UK.

## A puzzle

To make things more concrete, consider the following circuit:

2

After some deliberation you might realize that the seven-segment display shows the sequence `N`, `5`, `2`, `1`, `2`, `4`, `1`, `7` which you might recognize as the Northing of the Great Court3 Fountain.

Solving the problem by hand isn’t difficult: the circuit is structured to make manual simulation easy, and the task is guided by the test points shown on the left-hand side of the schematic.

However it’s always nice to make things with flashing lights, I had a iCE40 FPGA demo board on my desk, and this seemed worth a try:

## More LEDs!

The FPGA has many pins, so it seemed a shame to drive only a single digit:

## Verilog

Converting the schematic to verilog wasn’t hard, though there’s an off-by-one error somewhere which I bodged around.

The code below only covers the elements shown in the schematic, you need a bit more the generate the input clock and wire things up.

``````module puzzle(input clk
, input rst
, output [5:0] ta
, output [7:0] tb
, output [7:0] seg
, output [7:0] dig);

wire [2:0] qs;

counter c1 (.clk(clk), .rst(rst), .qs(qs));

gates gs (.q(qs), .ta(ta), .tb(tb), .seg(seg));

digits ds (.notSel(tb), .digs(dig));

endmodule

module counter(input clk, input rst, output [2:0] qs);
reg q0, q1, q2;

always @(posedge clk)
q0 <= (rst) ? 0 : !q0;

always @(posedge !q0)
q1 <= (rst) ? 0 : !q1;

always @(posedge !q1)
q2 <= (rst) ? 0 : !q2;

wire [2:0] qs;
assign qs = {q2, q1, q0};

endmodule

module digits(input  [7:0] notSel,
output [7:0] digs);

// odd offset here!
assign digs[0] = (notSel[6]) ? 0 : 1;
assign digs[1] = (notSel[5]) ? 0 : 1;
assign digs[2] = (notSel[4]) ? 0 : 1;
assign digs[3] = (notSel[3]) ? 0 : 1;
assign digs[4] = (notSel[2]) ? 0 : 1;
assign digs[5] = (notSel[1]) ? 0 : 1;
assign digs[6] = (notSel[0]) ? 0 : 1;
assign digs[7] = (notSel[7]) ? 0 : 1;

endmodule

module gates(input  [2:0] q,
output [5:0] ta,
output [7:0] tb,
output [7:0] seg);

assign ta[0] = !q[2];
assign ta[1] =  q[2];
assign ta[2] = !q[1];
assign ta[3] =  q[1];
assign ta[4] = !q[0];
assign ta[5] =  q[0];

assign tb[0] = !(ta[1] & ta[3] & ta[5]);
assign tb[1] = !(ta[1] & ta[3] & ta[4]);
assign tb[2] = !(ta[1] & ta[2] & ta[5]);
assign tb[3] = !(ta[1] & ta[2] & ta[4]);
assign tb[4] = !(ta[0] & ta[3] & ta[5]);
assign tb[5] = !(ta[0] & ta[3] & ta[4]);
assign tb[6] = !(ta[0] & ta[2] & ta[5]);
assign tb[7] = !(ta[0] & ta[2] & ta[4]);

assign seg[0] = !(tb[0] & tb[1] & tb[3]);
assign seg[1] = !tb[5];
assign seg[2] = !(tb[2] & tb[4]);
assign seg[3] =  tb[2] & tb[4] & tb[5];
assign seg[4] =  tb[2] & tb[4] & tb[6];
assign seg[5] =  tb[1] & tb[5] & tb[6];
assign seg[6] =  tb[1] & tb[2] & tb[4] & tb[5];
assign seg[7] =  tb[2] & tb[4];

endmodule   						``````

## Conclusion

So there you have it. This isn’t a particularly good way to solve the puzzle but it didn’t take long and has an impressive blinkenlight4 score.