--*************************************************************** --* File : CTLWB.vhd * --* Created : 2008/02/27 Osamu Kawashima * --* Modified : Time-stamp: <08/02/29 01:44:16 kawasan> * --* * --* Controller WISHBONE-I/F * --* * --* Copyright 2008 Osamu Kawashima. all rights reserved * --*************************************************************** library ieee; use ieee.std_logic_1164.all; entity CTLWB is port ( -- WISHBONE MASTER interface: WB_CLK_I : in std_logic; WB_RST_I : in std_logic; WB_ADR_O : out std_logic_vector(31 downto 0); WB_DAT_I : in std_logic_vector(31 downto 0); WB_DAT_O : out std_logic_vector(31 downto 0); WB_WE_O : out std_logic; WB_SEL_O : out std_logic_vector(3 downto 0); WB_STB_O : out std_logic; WB_ACK_I : in std_logic; -- Other port interface: ADR : in std_logic_vector(31 downto 0); DAT_I : in std_logic_vector(31 downto 0); DAT_O : out std_logic_vector(31 downto 0); WE : in std_logic; SIZE : in std_logic_vector(1 downto 0); GO : in std_logic; DONE : out std_logic ); end CTLWB; architecture RTL of CTLWB is constant ZERO32 : std_logic_vector(31 downto 0) := (others=>'0'); constant ONE32 : std_logic_vector(31 downto 0) := (others=>'1'); --type STATE is (S_STANDBY, S_ACTION, S_WAIT); --signal current_state : STATE; --signal next_state : STATE; constant S_STANDBY : std_logic_vector := x"0"; constant S_ACTION : std_logic_vector := x"1"; constant S_WAIT : std_logic_vector := x"2"; signal current_state : std_logic_vector(S_STANDBY'range); signal next_state : std_logic_vector(S_STANDBY'range); signal dat_i_t : std_logic_vector(DAT_I'range); signal wb_dat_i_t : std_logic_vector(WB_DAT_I'range); signal reg_adr : std_logic_vector(ADR'range); signal reg_dat_i : std_logic_vector(DAT_I'range); signal reg_dat_o : std_logic_vector(DAT_O'range); signal reg_we : std_logic; signal reg_stb : std_logic; signal reg_sel : std_logic_vector(WB_SEL_O'range); signal reg_done : std_logic; signal wb_sel_o_t : std_logic_vector(WB_SEL_O'range); signal f_action : std_logic; signal f_done : std_logic; begin -- State-Machine -- process (WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then current_state <= S_STANDBY; else current_state <= next_state; end if; end if; end process; process (current_state,f_action,WB_ACK_I) begin if current_state=S_STANDBY then if f_action='1' then next_state <= S_ACTION; else next_state <= S_STANDBY; end if; elsif current_state=S_ACTION then if WB_ACK_I='1' then next_state <= S_STANDBY; else next_state <= S_WAIT; end if; elsif current_state=S_WAIT then if WB_ACK_I='1' then next_state <= S_STANDBY; else next_state <= S_WAIT; end if; else next_state <= S_STANDBY; end if; end process; -- State-Machine -- f_action <= '1' when current_state=S_STANDBY and GO='1' else '0'; f_done <= '1' when (current_state=S_ACTION or current_state=S_WAIT) and WB_ACK_I='1' else '0'; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_adr <= (others=>'0'); elsif next_state=S_ACTION then reg_adr <= ADR; else reg_adr <= reg_adr; end if; end if; end process; WB_ADR_O <= reg_adr; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_dat_i <= (others=>'0'); elsif next_state=S_ACTION and WE='1' then reg_dat_i <= dat_i_t; else reg_dat_i <= reg_dat_i; end if; end if; end process; dat_i_t( 7 downto 0) <= DAT_I( 7 downto 0) when reg_sel(0)='1' else (others=>'0'); dat_i_t(15 downto 8) <= DAT_I(15 downto 8) when reg_sel(1)='1' else (others=>'0'); dat_i_t(23 downto 16) <= DAT_I(23 downto 16) when reg_sel(2)='1' else (others=>'0'); dat_i_t(31 downto 24) <= DAT_I(31 downto 24) when reg_sel(3)='1' else (others=>'0'); WB_DAT_O <= reg_dat_i; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_dat_o <= (others=>'0'); elsif f_done='1' and reg_we='0' then reg_dat_o <= wb_dat_i_t; else reg_dat_o <= reg_dat_o; end if; end if; end process; wb_dat_i_t( 7 downto 0) <= WB_DAT_I( 7 downto 0) when reg_sel(0)='1' else (others=>'0'); wb_dat_i_t(15 downto 8) <= WB_DAT_I(15 downto 8) when reg_sel(1)='1' else (others=>'0'); wb_dat_i_t(23 downto 16) <= WB_DAT_I(23 downto 16) when reg_sel(2)='1' else (others=>'0'); wb_dat_i_t(31 downto 24) <= WB_DAT_I(31 downto 24) when reg_sel(3)='1' else (others=>'0'); DAT_O <= reg_dat_o; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_we <= '0'; elsif next_state=S_ACTION then reg_we <= WE; else reg_we <= reg_we; end if; end if; end process; WB_WE_O <= reg_we; process(SIZE) begin if SIZE="00" then reg_sel <= "0001"; elsif SIZE="01" then reg_sel <= "0011"; elsif SIZE="10" then reg_sel <= "1111"; else reg_sel <= "0000"; end if; end process; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then wb_sel_o_t <= (others=>'0'); elsif next_state=S_ACTION then wb_sel_o_t <= reg_sel; else wb_sel_o_t <= wb_sel_o_t; end if; end if; end process; WB_SEL_O <= wb_sel_o_t; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_stb <= '0'; elsif next_state=S_ACTION then reg_stb <= '1'; elsif f_done='1' then reg_stb <= '0'; else reg_stb <= reg_stb; end if; end if; end process; WB_STB_O <= reg_stb; process(WB_CLK_I) begin if WB_CLK_I'event and WB_CLK_I='1' then if WB_RST_I='1' then reg_done <= '1'; elsif next_state=S_ACTION then reg_done <= '0'; elsif f_done='1' then reg_done <= '1'; else reg_done <= reg_done; end if; end if; end process; DONE <= reg_done; end RTL;