summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-12-28 02:37:20 -0700
committerJosh Rahm <joshuarahm@gmail.com>2022-12-28 02:37:20 -0700
commitc2381347678ed99571fd6899f1bb8ba8a2f8fc4c (patch)
tree21ab97b0ee77bf2f9a84235bf7249491ae87641a
parent40b224e0f7a565c9b1cfcc32243d2bf9af37cb39 (diff)
downloadverilog-c2381347678ed99571fd6899f1bb8ba8a2f8fc4c.tar.gz
verilog-c2381347678ed99571fd6899f1bb8ba8a2f8fc4c.tar.bz2
verilog-c2381347678ed99571fd6899f1bb8ba8a2f8fc4c.zip
Added (very) crude Collatz conjecture module.
-rw-r--r--collatz.v57
-rw-r--r--collatz_tb.v48
2 files changed, 105 insertions, 0 deletions
diff --git a/collatz.v b/collatz.v
new file mode 100644
index 0000000..e90c1bd
--- /dev/null
+++ b/collatz.v
@@ -0,0 +1,57 @@
+module collatz (
+ input clk,
+ input rst,
+
+ input wire [15:0] in_start,
+ input wire start_int,
+
+ output reg [15:0] o_count,
+ output finish_int
+);
+
+ localparam IDLE = 0;
+ localparam SPINNING = 1;
+ localparam WAIT_TICK = 2;
+
+ reg [1:0] state = 0;
+ reg [15:0] count = 0;
+ reg [15:0] n = 0;
+
+ wire is_even;
+
+ assign is_even = ~n[0];
+ assign finish_int = (n == 1 && state == IDLE);
+
+ always @(posedge start_int) begin
+ if (state == IDLE) begin
+ state <= SPINNING;
+ n <= in_start;
+ end
+ end
+
+ always @(posedge clk or posedge rst) begin
+ if (rst == 1'b1) begin
+ state <= IDLE;
+ count <= 0;
+ n <= 0;
+ end else if (state == IDLE) begin
+ n <= 0;
+ end else if (state == SPINNING) begin
+ if (n <= 1) begin
+ o_count = count;
+ state = WAIT_TICK;
+ // finish_int should be triggered.
+ end else begin
+ if (is_even) begin
+ n <= n >> 1;
+ end else begin
+ n <= n * 3 + 1;
+ end
+ count <= count + 1;
+ end
+ end else if (state == WAIT_TICK) begin
+ state <= IDLE;
+ end
+ end
+
+ endmodule
diff --git a/collatz_tb.v b/collatz_tb.v
new file mode 100644
index 0000000..7419d3f
--- /dev/null
+++ b/collatz_tb.v
@@ -0,0 +1,48 @@
+`timescale 1 ns / 10 ps
+
+module collatz_tb ();
+ reg clk = 0;
+ reg rst = 0;
+
+ wire finish;
+
+ localparam integer DURATION = 10_000;
+
+ always begin
+ #41.667;
+
+ clk = ~ clk;
+ end
+
+ reg [15:0] n = 9;
+ reg start_int;
+
+ wire [15:0] count_out;
+
+ collatz ctz (
+ .clk(clk),
+ .rst(rst),
+ .in_start(n),
+ .start_int(start_int),
+ .o_count(count_out),
+ .finish_int(finish)
+ );
+
+ initial begin
+ #10 rst = 1'b1;
+ #1 rst = 1'b0;
+ end
+
+ initial begin
+ $dumpfile("collatz_tb.vcd");
+ $dumpvars(0, collatz_tb);
+
+ #50 start_int = 1;
+ #10 start_int = 0;
+
+ #(DURATION);
+ $display("Finished!");
+ $finish;
+ end
+
+endmodule