b16508ff87322e6d6c7417cf5521e05c573fe434
[bos2k9.git] / bos2k9_pump.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- This entity is a drop-in replacement for `fhw_rs232.rs232_send`
5 -- which sends out 512 Bytes (buffered internally) at once.
6 --
7 -----------------------------------------------------------------------
8
9 library ieee;
10 use ieee.std_logic_1164.all;
11 use ieee.numeric_std.all;
12
13 library fhw_tools;
14 use fhw_tools.types.all;
15
16 use work.bos2k9_globals.all;
17
18 entity bos2k9_pump is
19   generic(
20     clock_divider  : positive;
21     parity_enabled : std_logic := '1');
22   port(
23     clock : in  std_logic;
24     reset : in  std_logic;
25     
26     txn : in  std_logic;
27     txd : in  std_logic_byte_t;
28     txb : out std_logic;
29     tx  : out std_logic);
30 end bos2k9_pump;
31
32 -----------------------------------------------------------------------
33
34 architecture rtl of bos2k9_pump is
35      component rs232_send is
36     generic(
37       clock_divider  : positive  := clock_divider;
38       parity_enabled : std_logic := parity_enabled);
39     port(
40       clk : in  std_logic;
41       rst : in  std_logic;
42       
43       tx  : out std_logic;
44       txd : in  std_logic_byte_t;
45       txn : in  std_logic;
46       txb : out std_logic);
47    end component;
48  
49    component bos2k9_mmu is
50     port(
51       clock : in  std_logic;
52       reset : in  std_logic;
53     
54       write_next : in  std_logic;
55       write_addr : out std_logic_byte_address_t;
56       write_data : in  std_logic_byte_t;
57     
58       read_addr : in  std_logic_byte_address_t;
59       read_data : out std_logic_byte_t);
60   end component;
61   
62   type state_t is(
63     idle_state_c,
64     send_state_c,
65     wait_state_c,
66     next_state_c);
67   signal state_s : state_t;
68
69   signal done_s : std_logic;
70   
71   signal sout_s : std_logic_byte_t;
72   signal strg_s : std_logic;
73   signal sbsy_s : std_logic;
74
75   signal addr_s : std_logic_byte_address_t;
76 begin
77   txb <= txn when state_s = idle_state_c
78     else '1';
79     
80   strg_s <= '1' when state_s = send_state_c
81        else '0';
82
83   sequence : process(clock, reset)
84   begin
85     if reset = '1' then
86       state_s <= idle_state_c;
87     elsif rising_edge(clock) then
88       case state_s is
89         when idle_state_c =>
90           if txn = '1' then
91             state_s <= send_state_c;
92           end if;
93         when send_state_c =>
94           state_s <= wait_state_c;
95         when wait_state_c =>
96           if sbsy_s = '0' then
97             state_s <= next_state_c;
98           end if;
99         when next_state_c =>
100           if done_s = '1' then
101             state_s <= send_state_c;
102           else
103             state_s <= idle_state_c;
104           end if;
105       end case;
106     end if;
107   end process;
108   
109   pointer : process(clock, reset)
110   begin
111     if reset = '1' then
112       addr_s <= (others => '0');
113     elsif rising_edge(clock) then
114       if state_s = next_state_c then
115         addr_s <= std_logic_vector(unsigned(addr_s) + 1);
116       end if;
117     end if;
118   end process;
119
120   done_net : process(addr_s)
121     variable done_v : std_logic;
122   begin
123     done_v := '1';
124     for i in std_logic_byte_address_t'range loop
125       done_v := done_v and addr_s(i);
126     end loop;
127     done_s <= done_v;
128   end process;
129   
130   ser_io : rs232_send port map(
131     clk => clock,
132     rst => reset,
133     
134     tx  => tx,
135     txd => sout_s,
136     txn => strg_s,
137     txb => sbsy_s);
138   mmu : bos2k9_mmu port map(
139     clock => clock,
140     reset => reset,
141     write_next => txn,
142     write_addr => open,
143     write_data => txd,
144     read_addr  => addr_s,
145     read_data  => sout_s);
146 end rtl;