9195e92238ae66cf23dc446ac78632dfe169f2e0
[bos2k9.git] / fhw_rs232 / rs232_send.vhd
1 -----------------------------------------------------------------------
2 -- Copyright (c) 2009 Malte S. Stretz <http://msquadrat.de> 
3 --
4 -- TODO
5 -- 
6 -----------------------------------------------------------------------
7 -- This entity is part of the following library:
8 -- pragma library fhw_rs232
9 library fhw_rs232;
10 use fhw_rs232.rs232_globals_p.all;
11
12 library ieee;
13 use ieee.std_logic_1164.all;
14 use ieee.numeric_std.all;
15
16 entity rs232_send is
17   generic(
18     clock_interval : time;
19     clock_divider  : positive; -- TODO: calculate this based on clock_interval
20     data_width     : positive := 8;
21     parity_enabled : std_logic := '0';
22     parity_type    : std_logic := '0');
23   port(
24     clk : in  std_logic;
25     rst : in  std_logic;
26     
27     tx  : out std_logic;
28     txd : in  std_logic_vector(data_width - 1 downto 0);
29     txn : in  std_logic;
30     txb : out std_logic);
31  end rs232_send;
32  
33 -----------------------------------------------------------------------
34
35 architecture rtl of rs232_send is
36   type state_t is (
37     state_idle_c,
38     state_send_c,
39     state_wait_c);
40   signal state_s : state_t;
41   
42   subtype frame_t is std_logic_vector(data_width - 1 + 2 + 1 downto 0);
43   signal frame_s : frame_t;
44   signal index_s : frame_t;
45   
46   signal timer_s : std_logic;
47   signal done_s  : std_logic;
48 begin
49   txb <= '0' when state_s = state_idle_c
50     else '1';
51   
52   frame_s(frame_t'high) <= '1';
53   frame_s(frame_t'high - 1) <= '0';
54   frame_s(frame_t'high - 2 downto frame_t'high - 2 - (data_width - 1)) <= txd;
55   frame_s(frame_t'low + 1) <= get_parity(txd, parity_type) when parity_enabled = '1'
56                          else frame_s(frame_t'low);
57   frame_s(frame_t'low) <= '1';
58   
59   done_s <= index_s(frame_t'low + 0) when parity_enabled = '1'
60        else index_s(frame_t'low + 1);
61
62   output : process(clk)
63     variable output_v : std_logic;
64   begin
65     output_v := '0';
66     for i in frame_t'high downto frame_t'low loop
67       output_v := output_v or (frame_s(i) and index_s(i));
68     end loop;
69     tx <= output_v;
70   
71     if rising_edge(clk) then
72       case state_s is
73         when state_idle_c =>
74           index_s(frame_t'high) <= '1';
75           index_s(frame_t'high - 1 downto frame_t'low) <= (others => '0');
76         when state_send_c =>
77           index_s <= '0' & index_s(frame_t'high downto frame_t'low + 1);
78         when others =>
79           null;
80       end case;
81     end if;
82   end process;
83   
84   sequence : process(clk, rst)
85   begin
86     if rst = '1' then
87       state_s <= state_idle_c;
88     elsif rising_edge(clk) then
89       case state_s is
90         when state_idle_c =>
91           if txn = '1' then
92             state_s <= state_send_c;
93           end if;
94         when state_send_c =>
95           state_s <= state_wait_c;
96         when state_wait_c =>
97           if timer_s = '1' then
98             if done_s = '1' then
99               state_s <= state_idle_c;
100             else
101               state_s <= state_send_c;
102             end if;
103           end if;
104       end case;
105     end if;
106   end process;
107   
108 end rtl;