library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
entity spi_ltc2600 is
generic(
- BITS : integer range 8 to 32 := 32;
- WAITCYCLES : integer range 2 to 1024 := 7
+ BITS : integer range 8 to 32 := 32;
+ WAITCYCLES : integer range 2 to 1024 := 7
);
port(
- CLK_IN : in std_logic;
- RESET_IN : in std_logic;
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
-- Slave bus
- BUS_READ_IN : in std_logic;
- BUS_WRITE_IN : in std_logic;
- BUS_BUSY_OUT : out std_logic;
- BUS_ACK_OUT : out std_logic;
- BUS_ADDR_IN : in std_logic_vector(4 downto 0);
- BUS_DATA_IN : in std_logic_vector(31 downto 0);
- BUS_DATA_OUT : out std_logic_vector(31 downto 0);
+ BUS_READ_IN : in std_logic;
+ BUS_WRITE_IN : in std_logic;
+ BUS_BUSY_OUT : out std_logic;
+ BUS_ACK_OUT : out std_logic;
+ BUS_ADDR_IN : in std_logic_vector(4 downto 0);
+ BUS_DATA_IN : in std_logic_vector(31 downto 0);
+ BUS_DATA_OUT : out std_logic_vector(31 downto 0);
-- SPI connections
- SPI_CS_OUT : out std_logic_vector(15 downto 0);
- SPI_SDI_IN : in std_logic;
- SPI_SDO_OUT : out std_logic;
- SPI_SCK_OUT : out std_logic
+ SPI_CS_OUT : out std_logic_vector(15 downto 0);
+ SPI_SDI_IN : in std_logic;
+ SPI_SDO_OUT : out std_logic;
+ SPI_SCK_OUT : out std_logic;
+ SPI_CLR_OUT : out std_logic_vector(15 downto 0)
);
end entity;
architecture spi_ltc2600_arch of spi_ltc2600 is
- type ram_t is array(0 to 15) of std_logic_vector(31 downto 0);
+ type ram_t is array(0 to 15) of std_logic_vector(31 downto 0);
signal ram : ram_t;
-
- signal ram_addr : integer range 0 to 31;
- signal ram_data : std_logic_vector(31 downto 0);
- signal ctrl_reg : std_logic_vector(31 downto 0);
- signal start : std_logic;
+
+ signal ram_addr : integer range 0 to 31;
+ signal ram_data : std_logic_vector(31 downto 0);
+ signal ctrl_reg : std_logic_vector(31 downto 0);
+ signal start : std_logic;
signal chipselect_reg : std_logic_vector(15 downto 0) := x"0001";
-
- signal spi_cs : std_logic_vector(15 downto 0);
- signal spi_sck : std_logic;
- signal spi_sd : std_logic;
-
+ signal clear_reg : std_logic_vector(15 downto 0) := x"0000";
+
+ signal spi_cs : std_logic_vector(15 downto 0);
+ signal spi_sck : std_logic;
+ signal spi_sd : std_logic;
+
signal word_count : integer range 0 to BITS-1;
signal bit_count : integer range 0 to BITS-1;
signal time_count : integer range 0 to WAITCYCLES;
signal readback : std_logic_vector(31 downto 0);
-
- type fsm_t is (IDLE, WAIT_STATE, SET, TOGGLE_CS, TOGGLE_CS_0, TOGGLE_CS_1, TOGGLE_CS_2, FINISH);
+
+ type fsm_t is (IDLE, WAIT_STATE, SET, TOGGLE_CS, TOGGLE_CS_0, TOGGLE_CS_1, TOGGLE_CS_2, FINISH);
signal fsm_state : fsm_t;
begin
PROC_MEM : process
- variable addr : integer range 0 to 15;
- begin
- wait until rising_edge(CLK_IN);
- addr := to_integer(unsigned(BUS_ADDR_IN(3 downto 0)));
-
- BUS_ACK_OUT <= '0';
- BUS_BUSY_OUT <= '0';
- start <= '0';
-
- if BUS_WRITE_IN = '1' then
- if fsm_state = IDLE then
- BUS_ACK_OUT <= '1';
- if BUS_ADDR_IN(4) = '0' then
- ram(addr) <= BUS_DATA_IN;
- elsif BUS_ADDR_IN(0) = '1' then
- ctrl_reg <= BUS_DATA_IN;
- start <= '1';
- else --if BUS_ADDR_IN(0) = '0' then
- chipselect_reg <= BUS_DATA_IN(15 downto 0);
- end if;
- else
- BUS_BUSY_OUT <= '1';
- end if;
- end if;
+ variable addr : integer range 0 to 15;
+ begin
+ wait until rising_edge(CLK_IN);
+ addr := to_integer(unsigned(BUS_ADDR_IN(3 downto 0)));
+
+ BUS_ACK_OUT <= '0';
+ BUS_BUSY_OUT <= '0';
+ start <= '0';
- if BUS_READ_IN = '1' then
+ if BUS_WRITE_IN = '1' then
+ if fsm_state = IDLE then
+ BUS_ACK_OUT <= '1';
if BUS_ADDR_IN(4) = '0' then
- BUS_DATA_OUT <= ram(addr);
- elsif BUS_ADDR_IN(0) = '1' then
- BUS_DATA_OUT <= ctrl_reg;
+ ram(addr) <= BUS_DATA_IN;
elsif BUS_ADDR_IN(1) = '1' then
- BUS_DATA_OUT <= readback;
- else --if BUS_ADDR_IN(1) = '0' then
- BUS_DATA_OUT(15 downto 0) <= chipselect_reg;
- BUS_DATA_OUT(31 downto 16) <= x"0000";
+ clear_reg <= BUS_DATA_IN(15 downto 0);
+ elsif BUS_ADDR_IN(0) = '1' then
+ ctrl_reg <= BUS_DATA_IN;
+ start <= '1';
+ else --if BUS_ADDR_IN(0) = '0' then
+ chipselect_reg <= BUS_DATA_IN(15 downto 0);
end if;
- BUS_ACK_OUT <= '1';
+ else
+ BUS_BUSY_OUT <= '1';
end if;
-
- ram_data <= ram(ram_addr);
-
- end process;
-
-
+ end if;
+
+ if BUS_READ_IN = '1' then
+ if BUS_ADDR_IN(4) = '0' then
+ BUS_DATA_OUT <= ram(addr);
+ elsif BUS_ADDR_IN(0) = '1' then
+ BUS_DATA_OUT <= ctrl_reg;
+ elsif BUS_ADDR_IN(1) = '1' then
+ BUS_DATA_OUT(15 downto 0) <= clear_reg;
+ BUS_DATA_OUT(31 downto 16) <= x"0000";
+ elsif BUS_ADDR_IN(1) = '1' then
+ BUS_DATA_OUT <= readback;
+ else --if BUS_ADDR_IN(1) = '0' then
+ BUS_DATA_OUT(15 downto 0) <= chipselect_reg;
+ BUS_DATA_OUT(31 downto 16) <= x"0000";
+ end if;
+ BUS_ACK_OUT <= '1';
+ end if;
+
+ ram_data <= ram(ram_addr);
+ end process;
+
+
- PROC_FSM : process begin
+
+ PROC_FSM : process
+ begin
wait until rising_edge(CLK_IN);
case fsm_state is
when IDLE =>
-
+
if start = '1' then
ram_addr <= 0;
word_count <= to_integer(unsigned(ctrl_reg(4 downto 0)));
spi_cs <= not chipselect_reg;
spi_sck <= '1';
else
- spi_cs <= x"ffff";
- spi_sck <= '1';
+ spi_cs <= x"ffff";
+ spi_sck <= '1';
end if;
when WAIT_STATE =>
if time_count = 0 then
- fsm_state <= SET;
+ fsm_state <= SET;
else
- time_count <= time_count - 1;
+ time_count <= time_count - 1;
end if;
when SET =>
time_count <= WAITCYCLES;
- spi_sck <= not spi_sck;
+ spi_sck <= not spi_sck;
if spi_sck = '1' then
- spi_sd <= ram_data(bit_count);
+ spi_sd <= ram_data(bit_count);
if bit_count /= 0 then
- bit_count <= bit_count - 1;
- fsm_state <= WAIT_STATE;
+ bit_count <= bit_count - 1;
+ fsm_state <= WAIT_STATE;
else
ram_addr <= ram_addr + 1;
bit_count <= BITS-1;
if ram_addr /= word_count -1 then
- if ctrl_reg(7) = '0' then --one CS phase
+ if ctrl_reg(7) = '0' then --one CS phase
fsm_state <= WAIT_STATE;
- else --one CS per word
- fsm_state <= TOGGLE_CS;
+ else --one CS per word
+ fsm_state <= TOGGLE_CS;
end if;
else
fsm_state <= FINISH;
end if;
end if;
else
- fsm_state <= WAIT_STATE;
- readback <= readback(30 downto 0) & SPI_SDI_IN;
+ fsm_state <= WAIT_STATE;
+ readback <= readback(30 downto 0) & SPI_SDI_IN;
end if;
when TOGGLE_CS =>
if time_count = 0 and spi_sck = '0' then
time_count <= 7;
spi_sck <= not spi_sck;
- readback <= readback(30 downto 0) & SPI_SDI_IN;
+ readback <= readback(30 downto 0) & SPI_SDI_IN;
elsif time_count = 0 and spi_sck = '1' then
- fsm_state <= TOGGLE_CS_0;
+ fsm_state <= TOGGLE_CS_0;
else
- time_count <= time_count - 1;
+ time_count <= time_count - 1;
end if;
when TOGGLE_CS_0 =>
- time_count <= time_count - 1;
- if time_count = 0 then
- spi_cs <= x"ffff";
- fsm_state <= TOGGLE_CS_1;
- time_count <= 7;
- end if;
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_cs <= x"ffff";
+ fsm_state <= TOGGLE_CS_1;
+ time_count <= 7;
+ end if;
when TOGGLE_CS_1 =>
- time_count <= time_count - 1;
- if time_count = 0 then
- spi_cs <= not chipselect_reg;
- bit_count <= BITS-1;
- fsm_state <= WAIT_STATE;
- time_count <= WAITCYCLES;
- end if;
- when TOGGLE_CS_2 =>
- time_count <= time_count - 1;
- if time_count = 0 then
- spi_sck <= not spi_sck;
- fsm_state <= WAIT_STATE;
- time_count <= WAITCYCLES;
- end if;
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_cs <= not chipselect_reg;
+ bit_count <= BITS-1;
+ fsm_state <= WAIT_STATE;
+ time_count <= WAITCYCLES;
+ end if;
+ when TOGGLE_CS_2 =>
+ time_count <= time_count - 1;
+ if time_count = 0 then
+ spi_sck <= not spi_sck;
+ fsm_state <= WAIT_STATE;
+ time_count <= WAITCYCLES;
+ end if;
when FINISH =>
if time_count = 0 and spi_sck = '0' then
time_count <= WAITCYCLES;
spi_sck <= not spi_sck;
- readback <= readback(30 downto 0) & SPI_SDI_IN;
+ readback <= readback(30 downto 0) & SPI_SDI_IN;
elsif time_count = 0 and spi_sck = '1' then
- fsm_state <= IDLE;
+ fsm_state <= IDLE;
else
- time_count <= time_count - 1;
+ time_count <= time_count - 1;
end if;
end case;
if RESET_IN = '1' then
fsm_state <= IDLE;
end if;
- end process;
+ end process;
+
+
-
-
-- Outputs
SPI_CS_OUT <= spi_cs;
SPI_SCK_OUT <= spi_sck;
SPI_SDO_OUT <= spi_sd;
+ SPI_CLR_OUT <= clear_reg;
-
-end architecture;
\ No newline at end of file
+
+end architecture;