08-19-2017 06:35 AM
Hello
I'm trying to design a general reset module for my FPGA controlled system and having trouble with the RESETbyte coming from computer through a UART_RX module. The UART_RX module receives different control commands from computer and RESET is one of them.
The planned structure is as below:
UART_RX receives BYTEs when they are sent from computer (START, STOP, RESET)
DEVICE_CONTROLLER (below) perform the process what the received byte will do. For Start, Stop and Period it is fine. Because Start and Stop reset each other and period is a stable value. When a new one received it is used so no problem. But the problem with Reset is, for my view, it must also reset itself in some way. When RESET byte is received it sends a bit '1' to a GENERAL RESET module which starts an FSM based reset process and keep the whole system in reset mode for 1 second. But since the DEVICE_CONTROLLER left the RESET bit as '1' GENERAL RESET never leaves the reset process and system stucks. So for this structure I need to reset the RESET bit in DEVICE CONTROLLER case statement but how? Or if you suggest anyother usefull structure it will be very nice as well :)
Thanks in advance :)
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Device_Controller is Port ( clk : IN STD_LOGIC ; CTRL_BYTE : IN STD_LOGIC_VECTOR(7 DOWNTO 0) ; RESET : OUT STD_LOGIC ; PERIOD : OUT STD_LOGIC_VECTOR(2 DOWNTO 0) ; OPERATION : OUT STD_LOGIC ); end Device_Controller; architecture Behavioral of Device_Controller is signal s_clk : STD_LOGIC ; signal s_RESET : STD_LOGIC ; signal s_CTRL_BYTE : STD_LOGIC_VECTOR(7 DOWNTO 0) ; signal s_PERIOD : STD_LOGIC_VECTOR(2 DOWNTO 0) ; SIGNAL s_OPERATION : STD_LOGIC ; begin s_clk <= clk ; RESET <= s_RESET ; s_CTRL_BYTE <= CTRL_BYTE ; process(s_clk, s_CTRL_BYTE) begin if ( rising_edge(s_clk) ) then case s_CTRL_BYTE is
when "01000001" => s_OPERATION <= '1' ; s_RESET <= '0' ; when "01000010" => s_OPERATION <= '0' ; s_RESET <= '0' ; when "01000011" => s_PERIOD <= "001" ; s_RESET <= '0' ; when "01000100" => s_PERIOD <= "010" ; s_RESET <= '0' ; when "01000101" => s_PERIOD <= "011" ; s_RESET <= '0' ; when "01000110" => s_PERIOD <= "100" ; s_RESET <= '0' ; when "01000111" => s_PERIOD <= "101" ; s_RESET <= '0' ; when "01001000" => s_RESET <= '1' ;
when others => end case ; end if ; end process; OPERATION <= s_OPERATION ; PERIOD <= s_PERIOD ; end Behavioral;
09-15-2017 01:56 AM
Hi @florentw
Thank you for these two guys for their support. What a pity I didn't find chance to try them because I solved this issue using another way, holding system in reset mode and send another byte to reset the RESET mode to normal condition. It is a bit weird but gave me progress for my design. Just in case I'll try these two suggestions and I think they look better than my one :) and then mark as answer at least one (hope two answer is possible) because I don't want to mark before trying.
Best Wishes...
08-19-2017 07:12 AM
Hey @macellan85,
Assuming that your 'reset' doesn't stop the clock, the simple approach of setting a sane default (no reset) is enough to make it work, for example like this:
process(s_clk) begin if rising_edge(s_clk) then s_RESET <= '0'; case s_CTRL_BYTE is ... when "01001000" => s_RESET <= '1' ; ... end case; end if; end;
Note that this assumes that s_CTRL_BYTE is changed during the reset procedure.
In case the reset procedure requires a 'single' clock cycle trigger you can simply code it like this:
process(s_clk) variable v_CTRL_BYTE := (others => '0'); begin if rising_edge(s_clk) then ... when "01001000" => if v_CTRL_BYTE /= s_CTRL_BYTE then s_RESET <= '1'; end if; ... end case; v_CTRL_BYTE := s_CTRL_BYTE; end if; end;
Note: you do not need to safe the entire BYTE a flag is enough.
Hope this helps,
Herbert
08-26-2017 12:09 AM
Another option that I've seen is to write a "reset controller" block. It could take either the reset pulse described by @hpoetzl or the static level you're writing out now. If I were writing it for your case, I'd have it take the system reset high whenever its "reset request" input goes high. I would hold the system reset output high for some number of clock cycles, then ignore the "reset request" input until it goes low. In other words, only respond when the request is high this cycle but was low the previous cycle, aka a rising-edge detector.
Enjoy!
- Ryan
08-28-2017 04:13 AM
Hi @macellan85,
If the answers provided by Herbert and Ryan are enough for you, please mark the best one as solution to close the thread.
Kind Regards,
Florent
09-15-2017 01:56 AM
Hi @florentw
Thank you for these two guys for their support. What a pity I didn't find chance to try them because I solved this issue using another way, holding system in reset mode and send another byte to reset the RESET mode to normal condition. It is a bit weird but gave me progress for my design. Just in case I'll try these two suggestions and I think they look better than my one :) and then mark as answer at least one (hope two answer is possible) because I don't want to mark before trying.
Best Wishes...
09-15-2017 03:24 AM
Hi @macellan85,
As your issue is solved, please close the thread by marking you response as a solution.
Thanks,
Florent