Something is conflicting.
[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_divider  : positive;
19     data_width     : positive := 8;
20     parity_enabled : std_logic := '0';
21     parity_type    : std_logic := '0');
22   port(
23     clk : in  std_logic;
24     rst : in  std_logic;
25     
26     tx  : out std_logic;
27     txd : in  std_logic_vector(data_width - 1 downto 0);
28     txn : in  std_logic;
29     txb : out std_logic);
30  end rs232_send;
31  
32 -----------------------------------------------------------------------
33
34 architecture rtl of rs232_send is
35   component rs232_counter_e is
36     generic(
37       count : positive := clock_divider);
38     port(
39       clock  : in  std_logic;
40       reset  : in  std_logic;
41       enable : in  std_logic;
42       
43       done : out std_logic);
44   end component;
45
46   type state_t is (
47     state_idle_c,
48     state_send_c,
49     state_wait_c);
50   signal state_s : state_t;
51   
52   subtype frame_t is std_logic_vector(data_width - 1 + 2 + 1 downto 0);
53   signal frame_s : frame_t;
54   signal index_s : frame_t;
55   
56   signal sending_s : std_logic;
57   signal timer_s   : std_logic;
58   
59   signal done_s  : std_logic;
60 begin
61   txb <= '0' when state_s = state_idle_c
62     else '1';
63   
64   frame_s(frame_t'high - 0) <= '1'; -- Stop
65   frame_s(frame_t'high - 1) <= get_parity(txd, parity_type) when parity_enabled = '1'
66                           else frame_s(frame_t'high);
67   frame_s(frame_t'high - 2 downto frame_t'high - 2 - (data_width - 1)) <= txd;
68   frame_s(frame_t'low + 1) <= '0'; -- Start
69   frame_s(frame_t'low + 0) <= '1'; -- Idle
70   
71   done_s <= index_s(frame_t'high - 0) when parity_enabled = '1'
72        else index_s(frame_t'high - 1);
73
74   output : process(frame_s, index_s)
75     variable output_v : std_logic;
76   begin
77     output_v := '0';
78     for i in frame_t'range loop
79       output_v := output_v or (frame_s(i) and index_s(i));
80     end loop;
81     tx <= output_v;
82   end process;
83   
84   shifter : process(clk)
85   begin
86     if rising_edge(clk) then
87       case state_s is
88         when state_idle_c =>
89           index_s <= "00000000001";
90         when state_send_c =>
91           index_s <= index_s(frame_t'high - 1 downto frame_t'low) & '0';
92         when others =>
93           null;
94       end case;
95     end if;
96   end process;
97   
98   sequence : process(clk, rst)
99   begin
100     if rst = '1' then
101       state_s <= state_idle_c;
102     elsif rising_edge(clk) then
103       case state_s is
104         when state_idle_c =>
105           if txn = '1' then
106             state_s <= state_send_c;
107           end if;
108         when state_send_c =>
109           state_s <= state_wait_c;
110         when state_wait_c =>
111           if timer_s = '1' then
112             if done_s = '1' then
113               state_s <= state_idle_c;
114             else
115               state_s <= state_send_c;
116             end if;
117           end if;
118       end case;
119     end if;
120   end process;
121   
122   sending_s <= '1' when state_s = state_wait_c
123           else '0';
124   trigger : rs232_counter_e port map(
125     clock  => clk,
126     reset  => rst,
127     enable => sending_s,
128     
129     done   => timer_s);
130 end rtl;