diff --git a/top.vhd b/top.vhd index 13c9708..1d0ac76 100644 --- a/top.vhd +++ b/top.vhd @@ -3,10 +3,10 @@ -- Project : tiny-xo2 ------------------------------------------------------------------------------- -- File : top.vhd --- Author : マリオ +-- Author : Mario Hüttel -- Company : -- Created : 2017-11-21 --- Last update: 2017-11-22 +-- Last update: 2017-11-23 -- Platform : -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- @@ -36,30 +36,37 @@ end entity config_top; architecture RTL of config_top is + type fsm_state_t is (IDLE, CMD, REPLY, HANG); + + + ----------------- RESET LOGIC ------------------------------ - signal dts_sync : std_logic_vector(2 downto 0) := (others => '0'); - signal rst : std_logic; -- reset (high active) + signal dts_sync : std_logic_vector(2 downto 0) := (others => '0'); + signal rst : std_logic; -- reset (high active) ----------------- UART RX ---------------------------------- - signal data_rx : std_logic_vector(7 downto 0); - signal byte_ready_rx : std_logic; - signal error_rx : std_logic; + signal data_rx : std_logic_vector(7 downto 0); + signal byte_ready_rx : std_logic; + signal error_rx : std_logic; ----------------- UART TX ---------------------------------- - signal data_tx : std_logic_vector(7 downto 0); - signal byte_ready_tx : std_logic; - signal busy_tx : std_logic; - - - signal config_busy : std_logic := '1'; -- indicates that the core is in configuration/waiting mode - -- and the user logic has to stay in reset - + signal data_tx : std_logic_vector(7 downto 0); + signal byte_ready_tx : std_logic; + signal busy_tx : std_logic; + signal config_busy : std_logic := '1'; -- indicates that the core is in configuration/waiting mode + -- and the user logic has to stay in reset + signal config_active : std_logic := '1'; -- configuration FSM active ---------------------------- Wishbone Bus ------------------------------------- - signal wb_cyc : std_logic; - signal wb_stb : std_logic; - signal wb_we : std_logic; - signal wb_adr : std_logic_vector(7 downto 0); - signal wb_dat_in : std_logic_vector(7 downto 0); - signal wb_dat_out : std_logic_vector(7 downto 0); - signal wb_ack : std_logic; + signal wb_cyc : std_logic; + signal wb_stb : std_logic; + signal wb_we : std_logic; + signal wb_adr : std_logic_vector(7 downto 0); + signal wb_dat_in : std_logic_vector(7 downto 0); + signal wb_dat_out : std_logic_vector(7 downto 0); + signal wb_ack : std_logic; + -------------------------------- State machine ----------------------------------- + signal state : fsm_state_t; + signal reply_is_error : std_logic; + signal bytecounter : integer range 0 to 3 := 0; + begin -- architecture RTL @@ -80,7 +87,6 @@ begin -- architecture RTL wb_ack_o => wb_ack, wbc_ufm_irq => open); - uart_rx_1 : entity work.uart_rx port map ( clk => clk, @@ -108,11 +114,25 @@ begin -- architecture RTL tx => uart_tx); - timeout_counter_gen : process(clk) is - variable cnt : integer range 0 to 40000; + -- set config_busy on reset and wait 0.25s. If FSM is not active + -- deassert config_busy + timeout_counter_busy_gen : process(clk, rst) is + variable cnt : integer range 0 to 3000000 := 3000000; -- 0.25 sec counter begin - -- TODO: implement timeout counter - end process timeout_counter_gen; + if rst = '1' then + cnt := 3000000; + config_busy <= '1'; + elsif rising_edge(clk) then + config_busy <= '1'; + if cnt /= 0 then + cnt := cnt - 1 + else + if config_active = '0' then + config_busy <= '0'; + end if; + end if; + end if; + end process timeout_counter_busy_gen; -- Generate reset pulse on rising edge of dts input @@ -141,6 +161,43 @@ begin -- architecture RTL end process user_logic_reset_gen; + controlFSM : process (clk, rst) is + begin -- process controlFSM + if rst = '1' then + state <= IDLE; + config_active <= '0'; + bytecounter <= 0; + reply_is_error <= '0'; + -- Wishbone + wb_cyc <= '0'; + wb_stb <= '0'; + wb_adr <= (others => '0'); + wb_dat_in <= (others => '0'); + -- UART TX + data_tx <= (others => '0'); + byte_ready_tx <= '0'; + elsif rising_edge(clk) then + case state is + when IDLE => + if byte_ready_rx = '1' and data_rx = x"D5" then -- Serial byte received. Is it the preambel? + state <= CMD; + bytecounter <= 0; + end if; + when CMD => + if byte_ready_rx = '1' then + -- TODO: Byte received. Do something + end if; + when REPLY => + -- TODO: if reply_is_error = '1' then: wait for response that + -- indicates that the error is handled. Then switch back to command + -- mode. Else; Just wait for response to be sent. + null; + when HANG => + state <= HANG; -- End of FSM. Only way out is a reset + end case; + end if; + end process controlFSM; + ------ Asynchronous output assignments ---------------