macellan
Newbie level 6
Hello
I'm trying to design a counter system on my FPGA board using VHDL. My design needs to receive some bytes as control signals like start, stop reset and measurement period info. For this purpose I have a UART module including both TX and RX serial lines and I'm also using a usb serial converter.
For processing the commands I have used a case block. Depending on the received byte I want to perform different tasks as it is indicated as start, stop, reset and period. I' ve attached the test bench files which shows everything is fine. However, in reality when I send a command through my GUI on computer first it works but then the next received byte changes the previous. So I can' t handle each different bytes or commands successfully.
How can I handle incoming bytes? Does anyone have any suggestion related to a modification or a different structure?
Thanks in advance...
stop_watch.vhd
device_controller.vhd
tb_period_selection.vhd
I'm trying to design a counter system on my FPGA board using VHDL. My design needs to receive some bytes as control signals like start, stop reset and measurement period info. For this purpose I have a UART module including both TX and RX serial lines and I'm also using a usb serial converter.
For processing the commands I have used a case block. Depending on the received byte I want to perform different tasks as it is indicated as start, stop, reset and period. I' ve attached the test bench files which shows everything is fine. However, in reality when I send a command through my GUI on computer first it works but then the next received byte changes the previous. So I can' t handle each different bytes or commands successfully.
How can I handle incoming bytes? Does anyone have any suggestion related to a modification or a different structure?
Thanks in advance...
stop_watch.vhd
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 --================================================================================== -- -- timer = 100.000.000) -> 1/1 second -- timer = 50.000.000) -> 1/2 second = 500 mili second -- timer = 25.000.000) -> 1/4 second = 250 mili second -- timer = 10.000.000) -> 1/10 second = 100 mili second -- timer = 100.000) -> 1/1000 second = 1 mili second -- timer = 50.000) -> 1/2000 second = 0.5 mili second = 500 micro second --=================================================================================== LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; entity Stop_Watch is Port ( clk : IN STD_LOGIC ; -- 100 MHz OPERATION : IN STD_LOGIC ; RESET : IN STD_LOGIC ; Period_Info : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ; SW_Period_Over_Flag : OUT STD_LOGIC ; Period : OUT INTEGER range 0 to 5*10E+3); end Stop_Watch; architecture Behavioral of Stop_Watch is signal s_clk : STD_LOGIC ; signal s_OPERATION : STD_LOGIC ; signal s_RESET : STD_LOGIC ; signal s_SW_Period_Over_Flag : STD_LOGIC ; signal s_Period_Info : STD_LOGIC_VECTOR(3 DOWNTO 0) ; signal i_Period : INTEGER range 0 to 5*10E+3 := 0; begin s_clk <= clk ; s_OPERATION <= OPERATION ; s_RESET <= RESET ; s_Period_Info <= Period_Info ; i_Period <= 1 when s_period_info = "0001" else 5 when s_period_info = "0010" else 10 when s_period_info = "0011" else 30 when s_period_info = "0100" else 60 when s_period_info = "0101" else 300 when s_period_info = "0110" else 600 when s_period_info = "0111" else 1800 when s_period_info = "1000" else 3600 when s_period_info = "1001" else 1 ; process(s_clk, s_OPERATION, s_RESET, i_Period ) variable v_timer : integer range 0 to 5*100E+6 := 0; variable v_timer_seconds : integer range 0 to 5*10E+3 := 0; begin if ( rising_edge( s_clk ) ) then if (s_OPERATION = '1') then if ( s_RESET = '1' ) then v_timer := 0 ; else if ( v_timer = 5 ) then v_timer := 0; if ( v_timer_seconds = i_Period) then v_timer_seconds := 0 ; s_SW_Period_Over_Flag <= '1'; else v_timer_seconds := v_timer_seconds + 1 ; s_SW_Period_Over_Flag <= '0'; end if; else s_SW_Period_Over_Flag <= '0'; v_timer := v_timer + 1 ; end if ; end if ; else v_timer := 0 ; end if ; end if ; end process ; SW_Period_Over_Flag <= s_SW_Period_Over_Flag ; Period <= i_Period ; end Behavioral;
device_controller.vhd
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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(3 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 := '0'; signal s_CTRL_BYTE : STD_LOGIC_VECTOR(7 DOWNTO 0) ; signal s_PERIOD : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0001"; SIGNAL s_OPERATION : STD_LOGIC := '0'; 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" => -- A start BYTE s_OPERATION <= '1' ; when "01000010" => -- B stop BYTE s_OPERATION <= '0' ; ------ PERIOD --------------------------------------------- when "01000011" => -- C 1 sec BYTE s_PERIOD <= "0001" ; when "01000100" => -- D 5sec BYTE s_PERIOD <= "0010" ; when "01000101" => -- E 10sec BYTE s_PERIOD <= "0011" ; when "01000110" => -- F 30sec BYTE s_PERIOD <= "0100" ; when "01000111" => -- G 1min BYTE s_PERIOD <= "0101" ; when "01001000" => -- H 5min BYTE s_PERIOD <= "0110" ; when "01001001" => -- I 10min BYTE s_PERIOD <= "0111" ; when "01001010" => -- J 30min BYTE s_PERIOD <= "1000" ; when "01001011" => -- K 1 hour BYTE s_PERIOD <= "1001" ; ---------------------------------------------------------- when "01001100" => -- L "set RESET" BYTE s_RESET <= '1' ; when "01001101" => -- M "reset RESET" BYTE s_RESET <= '0' ; when others => s_OPERATION <= '0' ; end case ; end if ; end process; OPERATION <= s_OPERATION ; PERIOD <= s_PERIOD ; end Behavioral;
tb_period_selection.vhd
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY TB_Period_Selection IS END TB_Period_Selection; ARCHITECTURE behavior OF TB_Period_Selection IS -- Clock period definitions constant clk_period : time := 10 ns; --Inputs signal clk : std_logic := '0'; signal s_CTRL_BYTE : std_logic_vector(7 downto 0) ; --:= (others => '0'); COMPONENT Device_Controller PORT( clk : IN std_logic ; CTRL_BYTE : IN std_logic_vector(7 downto 0); RESET : OUT std_logic ; PERIOD : OUT std_logic_vector(3 downto 0); OPERATION : OUT std_logic ); END COMPONENT; --Outputs and Inputs2 signal s_RESET : std_logic; signal s_PERIOD_info : std_logic_vector(3 downto 0); signal s_OPERATION : std_logic; COMPONENT Stop_Watch Port( clk : IN STD_LOGIC ; -- 100 MHz OPERATION : IN STD_LOGIC ; RESET : IN STD_LOGIC ; Period_Info : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ; SW_Period_Over_Flag : OUT STD_LOGIC ; Period : OUT INTEGER range 0 to 5*10E+3); END COMPONENT; --Outputs2 signal s_SW_Period_Over_Flag : std_logic; signal s_Period : integer range 0 to 5*10E+3 ; BEGIN -- Instantiate the Unit Under Test (UUT) uut: Device_Controller PORT MAP ( clk => clk , CTRL_BYTE => s_CTRL_BYTE , RESET => s_RESET , PERIOD => s_PERIOD_info , OPERATION => s_OPERATION ); -- Instantiate the Unit Under Test (UUT) uut2: Stop_Watch PORT MAP ( clk => clk , OPERATION => s_OPERATION, RESET => s_RESET, Period_Info => s_PERIOD_info, SW_Period_Over_Flag => s_SW_Period_Over_Flag, Period => s_Period); -- Clock process definitions clk_process :process begin clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; end process; -- Stimulus process stim_proc: process begin wait for clk_period*2; ------------------------------------------ s_CTRL_BYTE <= "01000101"; -- 10 SEC wait for clk_period*5; ------------------------------------------ s_CTRL_BYTE <= "01000001"; -- START wait for clk_period*10; ------------------------------------------ s_CTRL_BYTE <= "01000011"; -- 1 SEC wait for clk_period*5; s_CTRL_BYTE <= "01001100"; -- set RESET wait for clk_period*2; s_CTRL_BYTE <= "01001101"; -- reset RESET wait for clk_period*2; -- -- s_CTRL_BYTE <= "01000111"; -- 1 MIN -- wait for clk_period*2; -- -- s_CTRL_BYTE <= "01001011"; -- 1 HOUR -- wait for clk_period*2; -- -- ------------------------------------------ -- s_CTRL_BYTE <= "01000010"; -- STOP wait for clk_period*5; ------------------------------------------ -- s_CTRL_BYTE <= "01001100"; -- set RESET -- wait for clk_period*2; -- -- s_CTRL_BYTE <= "01001101"; -- reset RESET -- wait for clk_period*2; wait; end process; END;
Attachments
Last edited by a moderator: