summaryrefslogtreecommitdiffstats
path: root/async_8bit_bus_adapter_hw/hdl/async_8bit_bus_adapter.vhd
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