summaryrefslogtreecommitdiffstats
path: root/misc/wishbone/src/atomic32_access.vhd
blob: 9bc98257e1d4e65665b744a85eb703283eba6dcc (plain)
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
131
132
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library work;
--use work.phi_config.all;
use work.wishbone_pkg.all;

entity atomic32_access is
	port (	cpu_clk			: in std_logic;
			areset			: in std_logic;
	
			-- Wishbone from CPU interface
			wb_16_i			: in wishbone_bus_in;
			wb_16_o     	: out wishbone_bus_out;
			
			-- Wishbone to FPGA registers and ethernet core
			wb_32_i			: in wishbone_bus_out;
			wb_32_o			: out wishbone_bus_in);
end atomic32_access;

architecture behave of atomic32_access is

type eth_state_wr_type is (idle, lsb_msb, lsb, msb, write, ack, wait_st);
signal	eth_state_wr : eth_state_wr_type;				
type eth_state_rd_type is (idle, lsb_msb, lsb_read, lsb, wait_st2, msb);
signal eth_state_rd : eth_state_rd_type;			
signal core_data : std_logic_vector(31 downto 0);
signal core_addr : std_logic_vector(31 downto 0);

begin
	process(cpu_clk, areset)
	begin
		if areset = '1' then
			eth_state_wr <= idle;
			eth_state_rd <= idle;
			wb_32_o.stb <= '0';
			wb_32_o.cyc <= '0';
			wb_16_o.ack <= '0';
			core_data <= (others => '0');
			core_addr <= (others => '0');
		elsif (rising_edge(cpu_clk)) then
			
			case eth_state_wr is						--write cycle
				when idle =>
					if wb_16_i.cyc = '1' and wb_16_i.we = '1' then
						eth_state_wr <= lsb_msb;						
					end if;					
				when lsb_msb =>
					if wb_16_i.adr(1) = '0' then
						eth_state_wr <= lsb;
					end if;
					if wb_16_i.adr(1) = '1' then
						eth_state_wr <= msb;
					end if;
				when lsb =>
					core_data(15 downto 0) <= wb_16_i.dat(15 downto 0);
					wb_16_o.ack <= '1';
					eth_state_wr <= wait_st;
				when msb =>
					core_data(31 downto 16) <= wb_16_i.dat(31 downto 16);
					core_addr <= wb_16_i.adr(31 downto 2) & "00";
					eth_state_wr <= write;
				when write =>
					wb_32_o.dat <= core_data;
					wb_32_o.adr <= core_addr;
					wb_32_o.sel <= "1111";
					wb_32_o.we <= '1';
					wb_32_o.stb <= '1';
					wb_32_o.cyc <= '1';
					eth_state_wr <= ack;
				when ack =>
					if wb_32_i.ack = '1' then
						wb_16_o.ack <= '1';
						eth_state_wr <= wait_st;
						wb_32_o.stb <= '0';	
						wb_32_o.cyc <= '0';		
						wb_32_o.sel <= "0000";	
						wb_32_o.we <= '0';	
					end if;
				when wait_st =>
					wb_16_o.ack <= '0';
					eth_state_wr <= idle;
				when others =>
					eth_state_wr <= idle;
			end case;
	
			case eth_state_rd is						--read cycle
				when idle =>
					if wb_16_i.cyc = '1' and wb_16_i.we = '0' then
						core_addr <= wb_16_i.adr(31 downto 2) & "00";	
						eth_state_rd <= lsb_msb;
					end if;
				when lsb_msb =>
					if wb_16_i.adr(1) = '0' then
						wb_32_o.adr <= core_addr;
						eth_state_rd <= lsb_read;
					end if;
					if wb_16_i.adr(1) = '1' then
						wb_32_o.adr <= core_addr;
						eth_state_rd <= msb;
					end if;
				when lsb_read =>
					wb_32_o.sel <= "1111";
					wb_32_o.we <= '0';
					wb_32_o.stb <= '1';
					wb_32_o.cyc <= '1';							
                	eth_state_rd <= lsb;
				when lsb =>
					if wb_32_i.ack = '1' then									
						wb_32_o.sel <= "0000";
						wb_32_o.stb <= '0';
						wb_32_o.cyc <= '0';
						core_data <= wb_32_i.dat;
						wb_16_o.dat <= x"0000" & wb_32_i.dat(15 downto 0);							
						wb_16_o.ack <= '1';
						eth_state_rd <= wait_st2;
					end if;
				when wait_st2 =>
					wb_16_o.ack <= '0';
					eth_state_rd <= idle;
				when msb =>
					wb_16_o.ack <= '1';
					wb_16_o.dat <= core_data(31 downto 16) & x"0000";
					eth_state_rd <= wait_st2;
				when others =>
					eth_state_rd <= idle;
			end case;
		end if;
	end process;

end behave;
OpenPOWER on IntegriCloud