`timescale 1ns / 1ps module debouncer( reset, clk, noisy, clean ); input reset, clk, noisy; output clean; parameter NDELAY = 1000; parameter NBITS = 20; reg [NBITS-1:0] count; reg xnew, clean; always @(posedge clk) if (reset) begin xnew <= noisy; clean <= noisy; count <= 0; end else if(noisy != xnew) begin xnew <= noisy; count <= 0; end else if(count == NDELAY) clean <= xnew; else count <= count + 1; endmodule module diff( input clk_i, input rst_i, input sig_i, output reg val_o, output reg oneclk_o ); reg last_value; always @(posedge clk_i) if( rst_i ) begin oneclk_o <= 0; last_value <= 0; val_o <= 0; end else if( last_value != sig_i ) begin last_value <= sig_i; oneclk_o <= sig_i; val_o <= 1; end else begin oneclk_o <= 0; val_o <= 0; end endmodule module rot_ctrl( input clk_i, input rst_i, input rot_a_i, input rot_b_i, input[7:0] data_i, input data_val_i, input[7:0] step_i, input step_val_i, output[7:0] led_o, output [7:0] data_o, output [7:0] step_o ); reg[7:0] data; reg[7:0] step; reg stateA; reg stateB; assign led_o = data; assign step_o = step; assign data_o = data; wire rot_a_clean; wire rot_b_clean; debouncer debounceA(rst_i, clk_i, rot_a_i, rot_a_clean); debouncer debounceB(rst_i, clk_i, rot_b_i, rot_b_clean); wire rot_a_diff; wire rot_b_diff; wire rot_a_diff_val; wire rot_b_diff_val; diff diffA(clk_i, rst_i, rot_a_clean, rot_a_diff_val, rot_a_diff); diff diffB(clk_i, rst_i, rot_b_clean, rot_b_diff_val, rot_b_diff); always @(posedge clk_i) begin if (rot_a_diff_val) stateA <= rot_a_diff; else if (rot_b_diff_val) stateB <= rot_b_diff; end always @(posedge clk_i) if( rst_i ) step <= 1; else if( step_val_i ) step <= step_i; always @(posedge clk_i) begin if( rst_i ) data <= 0; else if( data_val_i ) data <= data_i; else if( rot_a_diff == 1 && stateB == 0 ) data <= data + step; if( rot_b_diff == 1 && stateA == 0 ) begin if( data < step ) data <= 0; else data <= data - step; end end endmodule