AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
SPI_if.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 15:14:35 08/04/2011
6 -- Design Name:
7 -- Module Name: SPI_if - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.STD_LOGIC_ARITH.ALL;
23 use IEEE.STD_LOGIC_UNSIGNED.ALL;
24 use IEEE.std_logic_misc.all;
25 use work.amc13_pack.all;
26 
27 -- Uncomment the following library declaration if using
28 -- arithmetic functions with Signed or Unsigned values
29 --use IEEE.NUMERIC_STD.ALL;
30 
31 -- Uncomment the following library declaration if instantiating
32 -- any Xilinx primitives in this code.
33 library UNISIM;
34 use UNISIM.VComponents.all;
35 
36 entity SPI_if is
37  Port ( SCK : in STD_LOGIC;
38  CSn : in STD_LOGIC;
39  MOSI : in STD_LOGIC;
40  MISO : out STD_LOGIC;
41  SN : in STD_LOGIC_VECTOR (8 downto 0);
42  IsT1 : in STD_LOGIC;
43  OT : in STD_LOGIC;
44  newIPADDR : out STD_LOGIC;
45  SPI_we : out STD_LOGIC;
46  en_RARP : out STD_LOGIC;
47  IPADDR : out STD_LOGIC_VECTOR (31 downto 0);
48  SPI_rdata : in STD_LOGIC_VECTOR (7 downto 0);
49  SPI_wdata : out STD_LOGIC_VECTOR (7 downto 0);
50  SPI_addr : out STD_LOGIC_VECTOR (7 downto 0));
51 end SPI_if;
52 
53 architecture Behavioral of SPI_if is
54 signal SPI_write : std_logic := '0';
55 signal SPI_read : std_logic := '0';
56 signal READ_STATUS : std_logic := '0';
57 signal WRITE_CTL : std_logic := '0';
58 signal BitCntr : std_logic_vector(4 downto 0) := (others => '0');
59 signal sr_in : std_logic_vector(6 downto 0) := (others => '0');
60 signal sr_out : std_logic_vector(7 downto 0) := (others => '0');
61 signal addr : std_logic_vector(15 downto 0) := (others => '0');
62 signal SPI_we_i : std_logic := '0';
63 signal SPI_we_q : std_logic := '0';
64 signal STATUS : std_logic_vector(7 downto 0) := x"10";
65 signal version : std_logic_vector(15 downto 0) := (others => '0');
66 signal MACADDR : std_logic_vector(47 downto 0) := (others => '0');
67 signal SLOT : std_logic_vector(7 downto 0) := (others => '0');
68 signal SPI_IPADDR : std_logic_vector(31 downto 0) := (others => '0');
69 signal IPADDR_i : std_logic_vector(31 downto 0) := (others => '0');
70 signal IPADDR_high : std_logic_vector(23 downto 0) := (others => '0');
71 signal NET_MASK : std_logic_vector(31 downto 0) := (others => '0');
72 signal BOOT_VECTOR : std_logic_vector(15 downto 0) := (others => '0');
73 begin
74 newIPADDR <= STATUS(5);
75 SPI_addr <= addr(7 downto 0);
76 SPI_we <= SPI_we_i;
77 SPI_wdata <= sr_in & MOSI;
78 MISO <= sr_out(7);
79 IPADDR <= IPADDR_i;
80 version <= T2_version when IsT1 = '0' else K7version;
81 MACADDR <= x"080030f30" & '0' & not SN(8) & '0' & not SN(7 downto 6) & '0' & SN(5 downto 0) when IsT1 = '0' else x"080030f30" & '0' & not SN(8) & '0' & not SN(7 downto 6) & '1' & SN(5 downto 0);
82 --IPADDR_high <= x"c0a801" when SN(7) = '1' else x"c0a802";
83 IPADDR_high <= x"c0a801" when SN(8 downto 7) = "11" else x"c0a802" when SN(8 downto 7) = "10" else x"c0a803" when SN(8 downto 7) = "01" else x"c0a804";
84 IPADDR_i <= (IPADDR_high & SN(6 downto 0) & IsT1) when STATUS(5) = '0' else SPI_IPADDR;
85 en_RARP <= '1' when STATUS(5) = '1' and SPI_IPADDR(31 downto 24) = x"00" else '0';
86 --IPADDR_i <= (x"c0a801" & SN(6 downto 0) & IsT1);
87 process(SCK, CSn, sr_in, MOSI)
88 variable in_byte : std_logic_vector(7 downto 0);
89 begin
90 in_byte := sr_in & MOSI;
91  if(CSn = '1')then
92  SPI_write <= '0';
93  SPI_read <= '0';
94  READ_STATUS <= '0';
95  WRITE_CTL <= '0';
96  SPI_we_i <= '0';
97  SPI_we_q <= '0';
98  BitCntr <= (others => '0');
99  elsif(SCK'event and SCK = '1')then
100  BitCntr(2 downto 0) <= BitCntr(2 downto 0) + 1;
101  if(BitCntr(2 downto 0) = "111")then
102  BitCntr(4) <= BitCntr(3) or BitCntr(4);
103  BitCntr(3) <= not BitCntr(3) or BitCntr(4);
104  end if;
105  if(BitCntr = "00111")then
106  if(in_byte = x"03")then
107  SPI_read <= '1';
108  else
109  SPI_read <= '0';
110  end if;
111  if(in_byte = x"02")then
112  SPI_write <= '1';
113  else
114  SPI_write <= '0';
115  end if;
116  if(in_byte = x"05")then
117  READ_STATUS <= '1';
118  else
119  READ_STATUS <= '0';
120  end if;
121  if(in_byte = x"07")then
122  WRITE_CTL <= '1';
123  else
124  WRITE_CTL <= '0';
125  end if;
126  end if;
127  if(BitCntr = "11110" and SPI_write = '1')then
128  SPI_we_i <= '1';
129  else
130  SPI_we_i <= '0';
131  end if;
132  SPI_we_q <= SPI_we_i;
133  end if;
134 end process;
135 process(SCK, sr_in, MOSI)
136 variable CONF :std_logic_vector(7 downto 0);
137 begin
138 CONF := sr_in & MOSI;
139  if(SCK'event and SCK = '1')then
140  sr_in <= sr_in(5 downto 0) & MOSI;
141  if(WRITE_CTL = '1' and BitCntr = "01111")then
142  STATUS(7) <= (STATUS(7) and not (CONF(7) and CONF(0))) or (CONF(7) and CONF(1));
143  STATUS(6) <= (STATUS(6) and not (CONF(6) and CONF(0))) or (CONF(6) and CONF(1));
144  STATUS(5) <= (STATUS(5) and not (CONF(5) and CONF(0))) or (CONF(5) and CONF(1));
145  STATUS(4) <= STATUS(4) and not (CONF(5) and CONF(1));
146  end if;
147  if(SPI_write = '1' and BitCntr = "11111" and or_reduce(addr(15 downto 4)) = '0')then
148  case addr(3 downto 0) is
149  when x"0" => SLOT <= CONF;
150  when x"1" => NET_MASK(31 downto 24) <= CONF;
151  when x"2" => NET_MASK(23 downto 16) <= CONF;
152  when x"3" => NET_MASK(15 downto 8) <= CONF;
153  when x"4" => NET_MASK(7 downto 0) <= CONF;
154  when x"5" => SPI_IPADDR(31 downto 24) <= CONF;
155  when x"6" => SPI_IPADDR(23 downto 16) <= CONF;
156  when x"7" => SPI_IPADDR(15 downto 8) <= CONF;
157  when x"8" => SPI_IPADDR(7 downto 0) <= CONF;
158  when x"9" => BOOT_VECTOR(15 downto 8) <= CONF;
159  when x"a" => BOOT_VECTOR(7 downto 0) <= CONF;
160  when others => null;
161  end case;
162  end if;
163  if(BitCntr = "01111")then
164  addr(15 downto 8) <= sr_in & MOSI;
165  elsif(BitCntr = "10111")then
166  addr(7 downto 0) <= sr_in & MOSI;
167  elsif((SPI_read = '1' and BitCntr = "11111") or SPI_we_q = '1')then
168  addr <= addr + 1;
169  end if;
170  end if;
171 end process;
172 STATUS(3) <= OT;
173 process(SCK)
174 begin
175  if(SCK'event and SCK = '0')then
176  if(READ_STATUS = '0' and (SPI_read = '0' or BitCntr(4) = '0' or BitCntr(3) = '0'))then
177  sr_out <= x"ff";
178  elsif(BitCntr(2 downto 0) = "000")then
179  if(READ_STATUS = '1' and BitCntr(4 downto 3) = "01")then
180  sr_out <= STATUS;
181  elsif(addr(15 downto 4) = x"008")then
182  case addr(3 downto 0) is
183  when x"0" => sr_out <= MACADDR(47 downto 40);
184  when x"1" => sr_out <= MACADDR(39 downto 32);
185  when x"2" => sr_out <= MACADDR(31 downto 24);
186  when x"3" => sr_out <= MACADDR(23 downto 16);
187  when x"4" => sr_out <= MACADDR(15 downto 8);
188  when x"5" => sr_out <= MACADDR(7 downto 0);
189  when x"6" => sr_out <= version(15 downto 8);
190  when x"7" => sr_out <= version(7 downto 0);
191  when x"8" => sr_out <= "0000000" & not SN(8);
192  when x"9" => sr_out <= not SN(7 downto 0);
193  when others => sr_out <= x"00";
194  end case;
195  elsif(or_reduce(addr(15 downto 4)) = '0')then
196  case addr(3 downto 0) is
197  when x"0" => sr_out <= SLOT;
198  when x"1" => sr_out <= NET_MASK(31 downto 24);
199  when x"2" => sr_out <= NET_MASK(23 downto 16);
200  when x"3" => sr_out <= NET_MASK(15 downto 8);
201  when x"4" => sr_out <= NET_MASK(7 downto 0);
202  when x"5" => sr_out <= SPI_IPADDR(31 downto 24);
203  when x"6" => sr_out <= SPI_IPADDR(23 downto 16);
204  when x"7" => sr_out <= SPI_IPADDR(15 downto 8);
205  when x"8" => sr_out <= SPI_IPADDR(7 downto 0);
206  when x"9" => sr_out <= BOOT_VECTOR(15 downto 8);
207  when x"a" => sr_out <= BOOT_VECTOR(7 downto 0);
208  when x"b" => sr_out <= IPADDR_i(31 downto 24);
209  when x"c" => sr_out <= IPADDR_i(23 downto 16);
210  when x"d" => sr_out <= IPADDR_i(15 downto 8);
211  when x"e" => sr_out <= IPADDR_i(7 downto 0);
212  when others => sr_out <= x"00";
213  end case;
214  else
215  sr_out <= x"00";
216  end if;
217  else
218  sr_out <= sr_out(6 downto 0) & '0';
219  end if;
220  end if;
221 end process;
222 
223 end Behavioral;
224