/* * misc.v * * vim: ts=4 sw=4 * * Misc peripheral functions * * Copyright (C) 2019-2020 Sylvain Munaut * SPDX-License-Identifier: CERN-OHL-S-2.0 */ `default_nettype none module misc ( // Button input wire btn, // Ticks input wire [7:0] tick_e1, input wire tick_usb_sof, // Reset request output wire rst_req, // Wishbone input wire [ 7:0] wb_addr, output reg [31:0] wb_rdata, input wire [31:0] wb_wdata, input wire wb_we, input wire wb_cyc, output reg wb_ack, // Clock / Reset input wire clk, input wire rst ); // Signals // ------- genvar i; // Bus wire bus_clr; reg bus_we_boot; reg bus_we_tick_sel; // Counters reg [1:0] tick_e1_sel[0:1]; wire [1:0] tick_e1_mux; wire [15:0] cap_e1[0:1]; wire [31:0] cnt_time; // Boot reg [1:0] boot_sel; reg boot_now; // Bus interface // ------------- // Ack always @(posedge clk) wb_ack <= wb_cyc & ~wb_ack; assign bus_clr = ~wb_cyc | wb_ack; // Write enables always @(posedge clk) if (bus_clr | ~wb_we) begin bus_we_boot <= 1'b0; bus_we_tick_sel <= 1'b0; end else begin bus_we_boot <= wb_addr == 4'h0; bus_we_tick_sel <= wb_addr == 4'h4; end // Read mux always @(posedge clk) if (bus_clr) wb_rdata <= 32'h00000000; else case (wb_addr[3:0]) 4'h4: wb_rdata <= { cap_e1[1], cap_e1[0] }; 4'h7: wb_rdata <= cnt_time; default: wb_rdata <= 32'hxxxxxxxx; endcase // Counters // -------- // E1 ticks always @(posedge clk) if (bus_we_tick_sel) begin tick_e1_sel[1] <= wb_wdata[17:16]; tick_e1_sel[0] <= wb_wdata[ 1: 0]; end assign tick_e1_mux[0] = tick_e1[{1'b0, tick_e1_sel[0]}]; assign tick_e1_mux[1] = tick_e1[{1'b1, tick_e1_sel[1]}]; capcnt #( .W(16) ) e1_cnt_I[1:0] ( .cnt_cur (), .cnt_cap ({ cap_e1[1], cap_e1[0] }), .inc ({ tick_e1_mux[1], tick_e1_mux[0] }), .cap (tick_usb_sof), .clk (clk), .rst (rst) ); // Time capcnt #( .W(32) ) time_cnt_I ( .cnt_cur (cnt_time), .cnt_cap (), .inc (1'b1), .cap (1'b0), .clk (clk), .rst (rst) ); // DFU / Reboot // ------------ always @(posedge clk or posedge rst) if (rst) begin boot_now <= 1'b0; boot_sel <= 2'b00; end else if (bus_we_boot) begin boot_now <= wb_wdata[2]; boot_sel <= wb_wdata[1:0]; end dfu_helper #( .TIMER_WIDTH(26), .BTN_MODE(3), .DFU_MODE(0) ) dfu_I ( .boot_sel(boot_sel), .boot_now(boot_now), .btn_pad (btn), .btn_val (), .rst_req (rst_req), .clk (clk), .rst (rst) ); endmodule // misc