Sfoglia il codice sorgente

add initial version of button logic + dummy usage

Krzysztof Skrzynecki 5 giorni fa
parent
commit
a310b26df0
3 ha cambiato i file con 117 aggiunte e 1 eliminazioni
  1. 1 0
      projects/riscv_usb/Makefile
  2. 105 0
      projects/riscv_usb/rtl/button.v
  3. 11 1
      projects/riscv_usb/rtl/top.v

+ 1 - 0
projects/riscv_usb/Makefile

@@ -12,6 +12,7 @@ PROJ_RTL_SRCS := $(addprefix rtl/, \
 	soc_spram.v \
 	sysmgr.v \
 	3signal.v \
+	button.v \
 	mailbox_wb.v \
 )
 PROJ_SIM_SRCS := $(addprefix sim/, \

+ 105 - 0
projects/riscv_usb/rtl/button.v

@@ -0,0 +1,105 @@
+module debouncer#(
+  parameter WIDTH = 20,
+  parameter LAG = 250000
+)(
+  input wire clk,
+  input wire nrst,
+  input wire butt,
+  output reg filtered
+);
+  reg [WIDTH-1:0] cnt;
+
+  reg prev_butt;
+  reg butt_buff;//just to make button synced with clock
+
+  always @(posedge clk or negedge nrst) begin
+    if(!nrst) begin
+      cnt<=LAG;
+      butt_buff<=0;
+      prev_butt<=0;
+      filtered<=0;
+    end else begin
+      if (prev_butt == butt_buff) begin
+        if (cnt) begin
+          cnt <= cnt-1;
+        end else begin
+          filtered <= butt_buff;
+        end
+      end else begin
+        cnt <= LAG;
+      end
+      prev_butt <= butt_buff;
+      butt_buff <= butt;
+    end
+  end
+endmodule
+
+module button#(
+  parameter WIDTH = 24,//2^24 corresponds to 0.67s max time
+  parameter DEBOUNCE_LAG = 250000, //250000 = 10ms
+  parameter FIRST_CLICK = 2500000,//100ms -> 2500000
+  parameter FREQ_START = 8333333,//(1/f) 3Hz -> 333ms -> 8333333
+  //parameter FREQ_DECREMENT = 12,// hardcoded -> percentage * 16: 12 -> 12/16 = 75% of prev each loop
+  parameter FREQ_MAX = 1250000//(1/f) 20Hz -> 50ms -> 1250000
+)(
+  input wire clk, //25MHz
+  input wire nrst,
+  input wire butt,
+
+  output reg [31:0] press_count
+);
+  reg butt_filt;
+
+  reg [WIDTH-1:0] time_cntr;
+  //reg [WIDTH-1:0] curr_period;
+  reg [WIDTH-1:0] next_period;
+
+  reg [WIDTH-1:0] period_decremented;
+
+  reg is_pressed;
+  reg if_increment;
+
+  debouncer#(.LAG(DEBOUNCE_LAG)) deb(
+    .clk(clk),
+    .nrst(nrst),
+    .butt(butt),
+    .filtered(butt_filt)
+  );
+
+  always @(posedge clk or negedge nrst) begin
+    if(!nrst) begin
+      press_count<=0;
+      time_cntr<=FIRST_CLICK;
+      next_period<=FREQ_START;
+      is_pressed<=0;
+      if_increment<=0;
+    end else begin
+      if_increment <= 0;
+
+      if(is_pressed) begin
+        if (time_cntr==0) begin
+          if_increment <= 1;
+
+          time_cntr <= next_period;
+          if (period_decremented < FREQ_MAX) begin
+            next_period <= FREQ_MAX;
+          end else begin
+            next_period <= period_decremented;
+          end
+        end else begin
+          time_cntr <= time_cntr-1;
+        end
+      end else begin
+        time_cntr<=FIRST_CLICK;
+        next_period<=FREQ_START;
+      end
+
+      is_pressed <= butt_filt;
+      press_count <= press_count + (if_increment | (!is_pressed & butt_filt));
+
+      //period_decremented <= (next_period>>4)*FREQ_DECREMENT; // we loose some prec here, but who cares with this time resolution
+      //12=0b1100
+      period_decremented <= ({next_period,1'h0} + {1'h0,next_period})>>2;
+    end
+  end
+endmodule

+ 11 - 1
projects/riscv_usb/rtl/top.v

@@ -248,12 +248,22 @@ module top (
         .Out3(out3)
     );
 
+	reg [31:0] pcount; //dummy variable + usage to make sure button will not be optimized out
+
+	button b1(
+		.clk(clk_24m),
+		.nrst(~rst),
+		.butt(btn_1),
+
+		.press_count(pcount)
+	);
+
     // TODO: dummy led onoff when value has been written
     always @(posedge clk_24m or posedge rst)
         if (rst) begin
             led[0] = 1'b0;
             led[1] = 1'b0;
-            led[2] = 1'b0;
+            led[2] = 1'b0 & pcount[25];
         end else if (period1 == 1) begin
             led[0] = 1'b1;
             led[1] = 1'b0;