add dice files
diff --git a/info.yaml b/info.yaml
index fef0d8b..e390bc8 100644
--- a/info.yaml
+++ b/info.yaml
@@ -3,8 +3,7 @@
 project:
   wokwi_id: 0
   source_files:        # If using an HDL, set wokwi_id as 0 and uncomment and list your source files here
-    - verilog/rtl/counter.v
-    - verilog/rtl/decoder.v
+    - verilog/rtl/user_module.v
   top_module:  "user_module"      # put the name of your top module here, make it unique by prepending your github username
 
 # As everyone will have access to all designs, try to make it easy for someone new to your design to know what
diff --git a/verilog/rtl/dice.v b/verilog/rtl/dice.v
new file mode 100644
index 0000000..5ee6d59
--- /dev/null
+++ b/verilog/rtl/dice.v
@@ -0,0 +1,20 @@
+// Structural top-level module of dice
+
+timeunit 1ns; timeprecision 10ps;
+
+module dice(
+  input wire Clock, nReset,
+  output wire TL, ML, BL, MC, TR, MR, BR
+);
+  wire [1:0] Ran;
+  wire [2:0] DiceValue;
+  
+  random rand1(.Clock(Clock), .nReset(nReset), .Ran(Ran));
+  control cont1(.Clock(Clock), .nReset(nReset), .Ran(Ran), .DiceValue(DiceValue));
+  encoder enc1(.DiceValue(DiceValue),
+    .L11(TL), .L31(TR),
+    .L12(ML), .L22(MC), .L32(MR),
+    .L13(BL), .L33(BR)
+  );
+  
+endmodule
diff --git a/verilog/rtl/dice_stim.v b/verilog/rtl/dice_stim.v
new file mode 100644
index 0000000..a029e2f
--- /dev/null
+++ b/verilog/rtl/dice_stim.v
@@ -0,0 +1,69 @@
+// Testbench for dice
+
+timeunit 1ns; timeprecision 10ps;
+
+module dice_stim();
+
+logic Clock, nReset;
+wire TL, TR, ML, MC, MR, BL, BR;
+
+dice dut1(.Clock(Clock), .nReset(nReset),
+  .TL(TL), .TR(TR),
+  .ML(ML), .MC(MC), .MR(MR),
+  .BL(BL), .BR(BR)
+);
+
+// Probe
+task display_signals;
+  $display($time, "  %d   %d         %b  %b  %b  %b  %b  %b  %b  ", dut1.Ran, dut1.DiceValue, TL, TR, ML, MC, MR, BL, BR);
+endtask
+
+initial begin
+  $display("                Time  Ran DiceValue TL TR ML MC MR BL BR");
+  $display("                ====  ============= ====================");
+  display_signals();
+  forever begin
+    // Print signals every 10 clock cycles
+    #100;
+    display_signals();
+    // Pause the sim
+    `ifndef NOPAUSE
+    $stop();
+    `endif 
+  end
+end
+
+// Stimuli
+initial begin
+  nReset = 0;
+  #2 nReset = 1;
+  // If stop is not included, there needs to be something to stop the sim
+  `ifdef NOPAUSE
+  #2400 $finish();
+  `endif
+end
+
+// 100 MHz clock
+always begin
+    Clock = 0;
+    #5 Clock = 1;
+    #5;
+end
+
+// Self-checking every 2 clock cycles
+integer ones, prev_count=0;
+always begin
+  #20;  
+  // Check DiceValue matches number of active LEDs
+  // Doesn't check the pattern, but doing so would amount to asserting the inverse of the design
+  ones =  $countones({TL, TR, ML, MC, MR, BL, BR});
+  assert (dut1.DiceValue == ones) else $error("DiceValue %d != number of active LEDs (%d)", dut1.DiceValue, ones);
+  // Check that the dice has not stayed on the same side
+  assert (ones != prev_count) else $error("Dice Value did not change in this cycle");
+  //Check for illegal rolls, ie to the opposite side of the dice
+  assert ((ones+prev_count)!= 7) else $error("Rolling from %d to %d not allowed", prev_count, ones);
+  prev_count = ones;
+
+end
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/dtype_synth.v b/verilog/rtl/dtype_synth.v
new file mode 100644
index 0000000..efeab9a
--- /dev/null
+++ b/verilog/rtl/dtype_synth.v
@@ -0,0 +1,20 @@
+// structural model of edge triggered D type
+
+module dtype(
+  output logic Q, nQ,
+  input wire D, Clk, nRst
+  );
+
+timeunit 1ns; timeprecision 10ps;
+
+always_ff @(posedge Clk, negedge nRst) begin
+  if(~nRst) begin
+    Q  <= 1'b0;
+    nQ <= 1'b1;
+  end else begin
+    Q  <= D;
+    nQ <= ~D;
+  end
+end
+
+endmodule
diff --git a/verilog/rtl/encoder.sv b/verilog/rtl/encoder.sv
new file mode 100644
index 0000000..33f0d5c
--- /dev/null
+++ b/verilog/rtl/encoder.sv
@@ -0,0 +1,27 @@
+// Behavioural model of LED encoder
+
+timeunit 1ns; timeprecision 10ps;
+
+module encoder(
+  input wire [2:0] DiceValue,
+  output wire L11, L12, L13, L21, L22, L23, L31, L32, L33
+ );
+   logic [8:0] output_leds;
+ 
+   // Reading left to right then down
+   assign {L11, L21, L31, L12, L22, L32, L13, L23, L33} = output_leds;
+   
+   always_comb begin
+     case (DiceValue)
+       3'd0: output_leds = 9'b000_000_000;
+       3'd1: output_leds = 9'b000_010_000;
+       3'd2: output_leds = 9'b100_000_001;
+       3'd3: output_leds = 9'b100_010_001;
+       3'd4: output_leds = 9'b101_000_101;
+       3'd5: output_leds = 9'b101_010_101;
+       3'd6: output_leds = 9'b101_101_101;
+       3'd7: output_leds = 9'b111_101_111;
+     endcase
+  end
+
+endmodule
diff --git a/verilog/rtl/fast_control.v b/verilog/rtl/fast_control.v
new file mode 100644
index 0000000..8746c54
--- /dev/null
+++ b/verilog/rtl/fast_control.v
@@ -0,0 +1,51 @@
+// control module. Can't get out of error states except with reset
+
+timeunit 1ns; timeprecision 10ps;
+
+module fast_control(
+    input wire Clock, nReset,
+    input wire [1:0] Ran,
+    output wire [2:0] DiceValue
+);
+
+logic [2:0] dice_val, next_dice_value;
+logic n_1_or_6, n_2_or_5, n_3_or_4, enable_reg;
+
+logic [2:0] gated[0:5];
+
+assign n_1_or_6 = !((dice_val==3'd1) | (dice_val==3'd6));
+assign n_2_or_5 = !((dice_val==3'd2) | (dice_val==3'd5));
+assign n_3_or_4 = !((dice_val==3'd3) | (dice_val==3'd4));
+
+//assign n_1_or_6 = !((!dice_val[2] & !dice_val[1]) | ( dice_val[2] &  dice_val[1]));
+//assign n_2_or_5 = !((!dice_val[2] & !dice_val[0]) | ( dice_val[2] &  dice_val[0]));
+//assign n_3_or_4 = !(( dice_val[1] &  dice_val[0]) | (!dice_val[1] & !dice_val[0]));
+
+//assign n_1_or_6 = !(dice_val[2] == dice_val[1]);
+//assign n_2_or_5 = !(dice_val[2] == dice_val[0]);
+//assign n_3_or_4 = !(dice_val[1] == dice_val[0]);
+
+assign DiceValue = dice_val;
+
+assign gated[0] = 3'd1 & {3{n_1_or_6 &  Ran[0] &  !Ran[1] }};
+assign gated[1] = 3'd2 & {3{n_2_or_5 &  Ran[0] & ( Ran[1]^n_3_or_4) }};
+assign gated[2] = 3'd3 & {3{n_3_or_4 &  Ran[0] &   Ran[1] }};
+assign gated[3] = 3'd4 & {3{n_3_or_4 & !Ran[0] &   Ran[1] }};
+assign gated[4] = 3'd5 & {3{n_2_or_5 & !Ran[0] & ( Ran[1]^n_3_or_4) }};
+assign gated[5] = 3'd6 & {3{n_1_or_6 & !Ran[0] &  !Ran[1] }};
+
+assign next_dice_value = gated[0] | gated[1] | gated[2] | gated[3] | gated[4] | gated[5];
+
+always_ff @(posedge Clock, negedge nReset) begin
+  if (!nReset) begin
+    enable_reg <= 1'b0;
+    dice_val <= 3'd1;
+  end else begin
+    enable_reg <= !enable_reg;
+    if(enable_reg) begin
+      dice_val <= next_dice_value;
+    end
+  end
+end
+
+endmodule
diff --git a/verilog/rtl/random.v b/verilog/rtl/random.v
new file mode 100644
index 0000000..cf9a328
--- /dev/null
+++ b/verilog/rtl/random.v
@@ -0,0 +1,24 @@
+// SystemVerilog structural model of a LFSR PRBS generator
+
+timeunit 1ns; timeprecision 10ps;
+
+module random(
+  input wire Clock, nReset,
+  output wire [1:0] Ran
+);
+
+  // SV support for arrays of instances
+  // https://stackoverflow.com/questions/1378159/can-we-have-an-array-of-custom-modules
+
+  wire [10:0] dff_inputs, dff_outputs, dff_noutputs;
+
+  dtype lfsr[10:0] (.Clk(Clock), .nRst(nReset), .D(dff_inputs), .Q(dff_outputs), .nQ(dff_noutputs));
+
+  // Connections - see lab book for sketches
+  xor feedback (dff_inputs[10], dff_outputs[0], dff_noutputs[2]);
+
+  assign Ran = dff_outputs[1:0];
+
+  assign dff_inputs[9:0] = dff_outputs[10:1];
+
+endmodule
diff --git a/verilog/rtl/tb_encoder.v b/verilog/rtl/tb_encoder.v
new file mode 100644
index 0000000..3b4b857
--- /dev/null
+++ b/verilog/rtl/tb_encoder.v
@@ -0,0 +1,35 @@
+// Testbench for encoder
+
+timeunit 1ns; timeprecision 10ps;
+
+module tb_encoder;
+
+logic [2:0] DiceValue;
+
+wire L11, L12, L13, L21, L22, L23, L31, L32, L33;
+
+encoder dut1(.DiceValue(DiceValue),
+  .L11(L11), .L21(L21), .L31(L31),
+  .L12(L12), .L22(L22), .L32(L32),
+  .L13(L13), .L23(L23), .L33(L33)
+);
+
+// Stimuli
+integer i;
+initial begin
+  for (i=0; i<7; i++) begin
+    DiceValue = i;
+	# 20;
+	assert ($countones({L11, L12, L13, L21, L22, L23, L31, L32, L33})==DiceValue);
+	# 20;
+  end
+  DiceValue = 7;
+  # 20;
+  assert ($countones({L11, L12, L13, L21, L22, L23, L31, L32, L33})==8);
+  # 20;
+  $finish();
+end
+
+
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/tb_random.v b/verilog/rtl/tb_random.v
new file mode 100644
index 0000000..1bcfee4
--- /dev/null
+++ b/verilog/rtl/tb_random.v
@@ -0,0 +1,47 @@
+// Testbench for random
+
+timeunit 1ns; timeprecision 10ps;
+
+module tb_random;
+
+wire [1:0] Ran;
+logic Clock, nReset;
+
+localparam integer cycles = 2047;
+
+logic [1:0] pr_sequence [0:cycles-1];
+
+random dut1(.Clock(Clock), .nReset(nReset),
+  .Ran(Ran)
+);
+
+
+// Stimuli
+integer i;
+initial begin
+  nReset = 0;
+  #2 nReset = 1;
+  #10;
+  
+  for (i=0; i<cycles; i++) begin
+    pr_sequence[i] = Ran;
+    #200;
+  end
+  
+  for (i=0; i<cycles; i++) begin
+    assert (pr_sequence[i] == Ran) else $error("Expected %d got %d", pr_sequence[i], Ran);
+    #200;
+  end
+
+  #100 $finish();
+
+end
+
+// 100 MHz clock
+always begin
+    Clock = 0;
+    #50 Clock = 1;
+    #50;
+end
+
+endmodule