element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Members
    Members
    • Benefits of Membership
    • Achievement Levels
    • Members Area
    • Personal Blogs
    • Feedback and Support
    • What's New on element14
  • Learn
    Learn
    • Learning Center
    • eBooks
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Dev Tools
    • Manufacturers
    • Raspberry Pi
    • RoadTests & Reviews
    • Avnet Boards Community
    • Product Groups
  • Store
    Store
    • Visit Your Store
    • Choose Another Store
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
Personal Blogs
  • Members
  • More
Personal Blogs
Legacy Personal Blogs OrangeCrab - improved reset block: How to use one single user button to do multiple tasks in an FPGA
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Blog Post Actions
  • Subscribe by email
  • More
  • Cancel
  • Share
  • Subscribe by email
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: dramoz
  • Date Created: 5 Nov 2021 6:27 PM Date Created
  • Views 370 views
  • Likes 1 like
  • Comments 0 comments
  • gotcha
  • sv
  • fpga
  • orangecrab
  • systemverilog
Related
Recommended

OrangeCrab - improved reset block: How to use one single user button to do multiple tasks in an FPGA

dramoz
dramoz
5 Nov 2021

The OrangeCrab Verilog example has an orangecrab_reset block that uses the user button to go into boot mode (DFU). Although I found it practical so you do not have to unplug and plug the board while pressing the user button-down, sometimes it is good to have a system reset button for your application (or you required a user button for something else).

I updated the block so you can have both functionalities on the board. A single "quick" press, will generate an internal pulse that can be used as a global system reset, or in this case, used to toggle the RGB LEDs.

 

The design also adds a simple XOR debouncer + timer to the usr_btn input.

 

/*
BSD Zero Clause License
Copyright (c) 2021 Danilo Ramos
*/

/*
Module to give multiple functionality to a user input (button) by different press/hold actions
- quick press: send system reset
- press and hold: send boot_rst
*/

`default_nettype none
module sys_boot_rst #(
  parameter CLK_FREQUENCY = 48000000,
  parameter BUTTON_LOGIC_LEVEL = 1,
  parameter SYS_RESET_LOGIC_LEVEL = 1,
  parameter SYS_RESET_LOGIC_DEBOUNCE_MS = 10,
  parameter BOOT_RESET_LOGIC_LEVEL = 1,
  parameter BOOT_LONG_PRESS_DURATION_MS = 1000
)
(
  input wire clk,
  input wire usr_btn,
  output logic sys_rst,
  output logic boot_rst
);
  // Reset logic
  logic [1:0] xor_path;
  localparam sys_CLKS = $rtoi($ceil(CLK_FREQUENCY/1000*SYS_RESET_LOGIC_DEBOUNCE_MS));
  localparam boot_CLKS = $rtoi($ceil(CLK_FREQUENCY/1000*BOOT_LONG_PRESS_DURATION_MS));
  localparam BOOT_CNT_WL = $clog2(boot_CLKS);
  logic [BOOT_CNT_WL:0] boot_counter = '0;
   
  // Send proper rst
  assign sys_rst = (boot_counter==sys_CLKS) ? (SYS_RESET_LOGIC_LEVEL) : (~SYS_RESET_LOGIC_LEVEL);
  assign boot_rst = (boot_counter>=boot_CLKS) ? (BOOT_RESET_LOGIC_LEVEL):(~BOOT_RESET_LOGIC_LEVEL);
   
  always @(posedge clk) begin
    xor_path <= {xor_path[0], usr_btn};
    if(^xor_path) begin
      boot_counter <= '0;
      end else begin
        if(xor_path[1]==BUTTON_LOGIC_LEVEL) begin
          if(boot_counter <= boot_CLKS) begin
            boot_counter <= boot_counter + 1;
          end else begin
        end
      end else begin
        boot_counter <= '0;
      end
    end
  end
   
endmodule

 

One SV gotcha I forgot from time to time is the parameter declaration. Parameters types are inferred from the value. Most of the time, as the keyword is used to declare small integer values it is OK. But occasionally I do some large integer math with parameters. I was getting an error during the simulation and I realized that the values of the parameters were ill-calculated.

Initially, I was using the formula below

localparam boot_CLKS = $rtoi($ceil((CLK_FREQUENCY*BOOT_LONG_PRESS_DURATION_MS)/1000));

to calculate the number of clocks required to validate a boot hold_n_press action. That gave me a value of 48e9 which is greater than 2^32. I changed the formula to:

localparam boot_CLKS = $rtoi($ceil(CLK_FREQUENCY/1000*BOOT_LONG_PRESS_DURATION_MS));

where the division is done first before the multiplication and the calculated value by the tools were correct.

 

I tried a couple of tools with similar results. Looking closely you can infer that the parameters are declared as 32bit signed integers (SV standard) and therefore the overflow in the multiplication is "expected".

A recommendation, which I usually forgot to follow, is to always assign a proper type to parameter, and localparam declarations if you are doing some extra math.

 

You can find the complete code with a testbench at https://github.com/dramoz/orangecrab/tree/dev/usr_rst

You can read more about the OrangeCrab in my roadtest review.

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2023 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • Facebook
  • Twitter
  • linkedin
  • YouTube