blob: 2f70731eee0e806c707e580ab41c385b8bcac2ef (
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
|
-- async_8bit_bus_adapter.vhd
-- This file was auto-generated as a prototype implementation of a module
-- created in component editor. It ties off all outputs to ground and
-- ignores all inputs. It needs to be edited to make it do something
-- useful.
--
-- This file will not be automatically regenerated. You should check it in
-- to your version control system if you want to keep it.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity async_8bit_bus_adapter is
generic (
AUTO_CLOCK_CLOCK_RATE : string := "-1"
);
port (
clk : in std_logic := '0'; -- clock.clk
rst_n : in std_logic := '0'; -- reset.reset_n
cs_n : in std_logic := '0'; -- avalon_slave.chipselect_n
address : in std_logic_vector(15 downto 0) := (others => '0'); -- .address
writedata : in std_logic_vector(7 downto 0) := (others => '0'); -- .writedata
wr_n : in std_logic := '0'; -- .write_n
rd_n : in std_logic := '0'; -- .read_n
byte_enable_n : in std_logic := '0'; -- .byte_enable_n
wait_n : out std_logic; -- .waitrequest_n
readdata : out std_logic_vector(7 downto 0); -- .readdata
b_reset_n : out std_logic; -- eight_bit_bus.export
b_cs_n : out std_logic; -- .export
b_rnw : out std_logic; -- .export
b_done_n : in std_logic := '0'; -- .export
b_addr : out std_logic_vector(15 downto 0); -- .export
b_data_in : in std_logic_vector(7 downto 0) := (others => '0'); -- .export
b_data_out : out std_logic_vector(7 downto 0) -- .export
);
end entity async_8bit_bus_adapter;
architecture rtl of async_8bit_bus_adapter is
signal state:std_logic_vector(3 downto 0);
begin
--readdata <= b_data_in;
b_reset_n <= rst_n;
-- the avalon bus is a little miserable in that it doesn't cycle CS for each transfer.
-- it does seem to honor the wait for the 2nd transfer so long as you assert it in the
-- correct cycle.
-- this fsm converts to a more usual asynchronus bus each cycle looks exactly like this
-- the slave sets b_done_n high
-- time passes
-- the master drops b_cs_n: b_addr, b_rnw and b_data_out are now valid and will remain so until b_cs_n goes high
-- time passes
-- the slave sets b_done_n low: b_data_in show be valid if b_rnw was high
-- time passes
-- the master raises b_cs_n
bus_fsm: process (rst_n,clk,cs_n,wr_n,rd_n,b_done_n) begin
if (rst_n ='0') then
state <= "1000";
wait_n <= '1';
b_cs_n <='1';
readdata <= "10101111";
elsif rising_edge(clk) then
if state = "0001" then
readdata <="00010001";
if cs_n='0' and b_done_n='1' then
-- so it turns out avalon lies, address isn't valid this cycle
readdata <="00100010";
state <="0010";
end if;
elsif state = "0010" then
--address b_rnw and b_dat_out now valid
b_addr <=address;
b_data_out <= writedata;
b_rnw <= wr_n;
b_cs_n<='0';
readdata <="00110011";
state <= "0100";
elsif state = "0100" then
readdata <="01000100";
if b_done_n ='0' then
b_cs_n <= '1';
-- data is read during this cycle
readdata <=b_data_in;
wait_n<='1';
state <="1000";
end if;
elsif state = "1000" then
wait_n <= '0';
state <="0001";
else
state <="1000";
end if;
end if;
end process;
end architecture rtl; -- of async_8bit_bus_adapter
|