Yann pointed out in a comment that a Johnson counter may be a good way to save some gates in the logic implementation of the dice. Currently a simple binary counter is used.
To be honest, it seems that I mistakenly thought of Johnson counters being simple ring counter with one flipflop per state, when in fact they are a nice concept to reduce the number of flipflops needed for a counter by two compary to a ring counter. Even the Wikipedia entry throws Johnson counter and ring counters into one category, which is a bit confusing.
A fairly nice property of a Johnson counter implementation is that it is possible to implement a counter that comes with a natural sequence length of 6, exactly what we need for the dice. So, in contrast to the binary counter, no additional logic is needed to limit the sequence length.
Some caveats
- The sequence is not in order, since it does not follow binary encoding
- The sequence contains "000", which is currently not decoded as a valid face figure on the die.
- There are illegal states of the counter, so it has to be initialized
1) is not really an issue, since we want to randmize the die anyways. So we just accept that the sequence is different. 2) can be solved by inverting the middle bit. See below. 3) requires is to add a reset input. But the NE555 comes with a reset input anyways, so that is almost for free.
Sequence johnson counter middle bit inverted dice pattern
Seq1 000 010 2
Seq2 001 011 3
Seq3 011 001 1
Seq4 111 101 5
Seq5 110 100 4
Seq6 100 110 6
Here comes the VHDL implementation of the modified dice:
architecture main of dice555johnson is
signal cnt: unsigned(2 downto 0);
begin
process (clk,n_clk,nreset)
begin
if nreset = '0' then
cnt <= "000";
elsif rising_edge(clk) then
cnt <= cnt(1 downto 0) & NOT cnt(2);
end if;
end process;
-- 1 2
-- 3 0 3
-- 2 1
-- Encoding:
-- 011 0
-- 000 1
-- 001 0,1
-- 110 1,2
-- 111 0,1,2
-- 100 1,2,3
-- drive inverted LEDs
dice(0) <= NOT cnt(0);
dice(1) <= '1' when (cnt = "011") else '0';
dice(2) <= NOT cnt(2);
dice(3) <= '0' when (cnt = "100") else '1';
end;
And here are the design stats after synthesis:
Number of cells: 9
ne_DFF_clear 3
ne_NAND3 2
ne_NOT 4
Chip area for module '\main': 23.000000
Spice netlist
.SUBCKT main clk n_clk nrst dice.0 dice.1 dice.2 dice.3
X0 cnt.1 1 ne_NOT
X1 cnt.2 dice.2 ne_NOT
X2 cnt.0 dice.0 ne_NOT
X3 1 cnt.2 dice.0 dice.3 ne_NAND3
X4 cnt.1 dice.2 cnt.0 2 ne_NAND3
X5 2 dice.1 ne_NOT
X6 clk nrst dice.2 cnt.0 ne_DFF_clear
X7 clk nrst cnt.0 cnt.1 ne_DFF_clear
X8 clk nrst cnt.1 cnt.2 ne_DFF_clear
.ENDS main
Compared to the stats of the original implementation with binary counter:
Number of cells: 18
ne_DFF 3
ne_NAND2 7
ne_NAND3 2
ne_NOT 6
Chip area for module '\main': 39.000000
Quite impressive! Thanks for the tip, Yann. Will I build this? Probably not, I trust that it would work and I think owning one NE555 based electronic dice is already enough :)
Edit: Digital simulation output is shown below. Please note, that the dice output is inverted since the LEDs are active low. I found a tiny bug, which is fixed above.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
You're welcome, @Tim ! Maybe you can make such a dice with LTL or DCTL ? I'd be proud to have one ;-)
Are you sure? yes | no
LTL, indeed. One can never have enough LTL designs:
https://hackaday.io/page/11708-ltl-gen2-dice
This is the, yet unreleleased, Gen2 LTL technology with even more LEDs, higher density and lower cost!
You will get one, of course.
Are you sure? yes | no
oh my... that's too awesome !!!
Are you sure? yes | no
Another fast (no carry) psuedorandom counter is a Linear Feedback Shift Register, though makes for 7 sided die where 111 isn't allowed. NXOR the high bits, shift left, 000 001 011 110 101 010 100, repeat. Best for large counts that carry would slow and a pandom final count doesn't change. Adjust pattern of parity taps to assure enough states are countable, ideally all but one. If you display the output to emphasize flawed randomness rather than obscure it, you may observe bit serial cellular automata. You are doing the same basic thing, but with one tap parity....
Are you sure? yes | no
Yes, indeed, LFSRs are very useful. Problem is, this die is six sided :) One could probably add some logic to limit the sequence, though.
Are you sure? yes | no
And what exactly is your problem with seven sided dice?
Jammed forbidden state could work to reperesent zero pips till purposely upset.
But to stop and display other pip counts, one jammed state is not a complete plan.
Were you planning to pause or latch the primitive six transistor three flipflop ring?
Are you sure? yes | no
It's a good question. But why not go straight to eight? Zero pips are also an option.
⚀ ⚁ ⚂ ⚃ ⚄ ⚅
If you want a six sided dice, then the length of the counter should be exactly six, otherwise the propabilities are off. So extranouse states really need to be skipped. Reassigning them to other face counts would not be sufficient.
Are you sure? yes | no