diff options
Diffstat (limited to 'collatz.v')
-rw-r--r-- | collatz.v | 65 |
1 files changed, 44 insertions, 21 deletions
@@ -1,27 +1,44 @@ +/** + * Collatz Conjecture module. + * + * Takes a start integer and calculates the number of steps + * required for that number to get down to 1 using the collatz + * conjecture. + */ module collatz ( - input clk, - input rst, + /* Input clock and reset pin. */ + input clk, + input rst, - input wire [15:0] in_start, - input wire start_int, + /* The number to calculate. */ + input wire [15:0] in_start, + /* Pulsing the start_int pin will start the calculation. */ + input wire start_int, - output reg [15:0] o_count, - output finish_int -); + /* Output count. */ + output reg [15:0] o_count, - localparam IDLE = 0; - localparam SPINNING = 1; - localparam WAIT_TICK = 2; + /* Set to high when the module is idle and ready to start. + * While computing, this output is set to low. + * + * A positive edge of this will indicate the output is ready + * to be consumed. */ + output idle +); - reg [1:0] state = 0; - reg [15:0] count = 0; - reg [15:0] n = 0; + // Define some state parameters. + localparam integer IDLE = 0; + localparam integer SPINNING = 1; - wire is_even; + reg state = 0; // IDLE or SPINNING + reg [15:0] count = 0; // Current count + reg [15:0] n = 0; // Current value - assign is_even = ~n[0]; - assign finish_int = (n == 1 && state == IDLE); + wire is_even = ~n[0]; // Is the current value even. + assign idle = state == IDLE; + // When the start_int input is set to high, copy the in_start to the current + // number and set the state to SPINNING. always @(posedge start_int) begin if (state == IDLE) begin state <= SPINNING; @@ -29,29 +46,35 @@ module collatz ( end end + // Each clock cycle, determine what needs to happen. always @(posedge clk or posedge rst) begin + // On reset, reset the state. if (rst == 1'b1) begin state <= IDLE; count <= 0; n <= 0; + + // If the state is idle, reset the count to 0. end else if (state == IDLE) begin n <= 0; + + // If the state is calculating, do the next step. end else if (state == SPINNING) begin + // If n is 1, then set the output and go back to the IDLE state. if (n <= 1) begin o_count = count; - state = WAIT_TICK; - // finish_int should be triggered. + state = IDLE; end else begin + // If is_even, divide by two, otherwise multiply by 3 and add 1. if (is_even) begin n <= n >> 1; end else begin n <= n * 3 + 1; end + // Increment the count. count <= count + 1; end - end else if (state == WAIT_TICK) begin - state <= IDLE; end end - endmodule +endmodule |