OpenCores
URL https://opencores.org/ocsvn/spacewire_light/spacewire_light/trunk

Subversion Repositories spacewire_light

[/] [spacewire_light/] [trunk/] [rtl/] [vhdl/] [spwxmit.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jorisvr
--
2
--  SpaceWire Transmitter
3
--
4
--  This entity translates outgoing characters and tokens into
5
--  data-strobe signalling.
6
--
7
 
8
library ieee;
9
use ieee.std_logic_1164.all;
10
use ieee.numeric_std.all;
11
use work.spwpkg.all;
12
 
13
entity spwxmit is
14
 
15
    port (
16
        -- System clock.
17
        clk:        in  std_logic;
18
 
19
        -- Synchronous reset (active-high).
20
        rst:        in  std_logic;
21
 
22
        -- Scaling factor minus 1, used to scale the system clock into the
23
        -- transmission bit rate. The system clock is divided by
24
        -- (unsigned(divcnt) + 1). Changing this signal will immediately
25
        -- change the transmission rate.
26
        divcnt:     in  std_logic_vector(7 downto 0);
27
 
28
        -- Input signals from spwlink.
29
        xmiti:      in  spw_xmit_in_type;
30
 
31
        -- Output signals to spwlink.
32
        xmito:      out spw_xmit_out_type;
33
 
34
        -- Data Out signal to SpaceWire bus.
35
        spw_do:     out std_logic;
36
 
37
        -- Strobe Out signal to SpaceWire bus.
38
        spw_so:     out std_logic
39
    );
40
 
41
end entity spwxmit;
42
 
43
architecture spwxmit_arch of spwxmit is
44
 
45
    -- Registers
46
    type regs_type is record
47
        -- tx clock
48
        txclken:    std_ulogic;         -- high if a bit must be transmitted
49
        txclkcnt:   unsigned(7 downto 0);
50
        -- output shift register
51
        bitshift:   std_logic_vector(12 downto 0);
52
        bitcnt:     unsigned(3 downto 0);
53
        -- output signals
54
        out_data:   std_ulogic;
55
        out_strobe: std_ulogic;
56
        -- parity flag
57
        parity:     std_ulogic;
58
        -- pending time tick
59
        pend_tick:  std_ulogic;
60
        pend_time:  std_logic_vector(7 downto 0);
61
        -- transmitter mode
62
        allow_fct:  std_ulogic;         -- allowed to send FCTs
63
        allow_char: std_ulogic;         -- allowed to send data and time
64
        sent_null:  std_ulogic;         -- sent at least one NULL token
65
        sent_fct:   std_ulogic;         -- sent at least one FCT token
66
    end record;
67
 
68
    -- Initial state
69
    constant regs_reset: regs_type := (
70
        txclken     => '0',
71
        txclkcnt    => "00000000",
72
        bitshift    => (others => '0'),
73
        bitcnt      => "0000",
74
        out_data    => '0',
75
        out_strobe  => '0',
76
        parity      => '0',
77
        pend_tick   => '0',
78
        pend_time   => (others => '0'),
79
        allow_fct   => '0',
80
        allow_char  => '0',
81
        sent_null   => '0',
82
        sent_fct    => '0' );
83
 
84
    -- Registers
85
    signal r:       regs_type := regs_reset;
86
    signal rin:     regs_type;
87
 
88
begin
89
 
90
    -- Combinatorial process
91
    process (r, rst, divcnt, xmiti) is
92
        variable v: regs_type;
93
    begin
94
        v := r;
95
 
96
        -- Generate TX clock.
97
        if r.txclkcnt = 0 then
98
            v.txclkcnt  := unsigned(divcnt);
99
            v.txclken   := '1';
100
        else
101
            v.txclkcnt  := r.txclkcnt - 1;
102
            v.txclken   := '0';
103
        end if;
104
 
105
        if xmiti.txen = '0' then
106
 
107
            -- Transmitter disabled; reset state.
108
            v.bitcnt     := "0000";
109
            v.parity     := '0';
110
            v.pend_tick  := '0';
111
            v.allow_fct  := '0';
112
            v.allow_char := '0';
113
            v.sent_null  := '0';
114
            v.sent_fct   := '0';
115
 
116
            -- Gentle reset of spacewire bus signals
117
            if r.txclken = '1' then
118
                v.out_data   := r.out_data and r.out_strobe;
119
                v.out_strobe := '0';
120
            end if;
121
 
122
        else
123
            -- Transmitter enabled.
124
 
125
            v.allow_fct  := (not xmiti.stnull) and r.sent_null;
126
            v.allow_char := (not xmiti.stnull) and r.sent_null and
127
                            (not xmiti.stfct) and r.sent_fct;
128
 
129
            -- On tick of transmission clock, put next bit on the output.
130
            if r.txclken = '1' then
131
 
132
                if r.bitcnt = 0 then
133
 
134
                    -- Need to start a new character.
135
                    if (r.allow_char = '1') and (r.pend_tick = '1') then
136
                        -- Send Time-Code.
137
                        v.out_data  := r.parity;
138
                        v.bitshift(12 downto 5) := r.pend_time;
139
                        v.bitshift(4 downto 0)  := "01111";
140
                        v.bitcnt    := to_unsigned(13, v.bitcnt'length);
141
                        v.parity    := '0';
142
                        v.pend_tick := '0';
143
                    elsif (r.allow_fct = '1') and (xmiti.fct_in = '1') then
144
                        -- Send FCT.
145
                        v.out_data  := r.parity;
146
                        v.bitshift(2 downto 0)  := "001";
147
                        v.bitcnt    := to_unsigned(3, v.bitcnt'length);
148
                        v.parity    := '1';
149
                        v.sent_fct  := '1';
150
                    elsif (r.allow_char = '1') and (xmiti.txwrite = '1') then
151
                        -- Send N-Char.
152
                        v.bitshift(0) := xmiti.txflag;
153
                        v.parity    := xmiti.txflag;
154
                        if xmiti.txflag = '0' then
155
                            -- Data byte
156
                            v.out_data  := not r.parity;
157
                            v.bitshift(8 downto 1) := xmiti.txdata;
158
                            v.bitcnt    := to_unsigned(9, v.bitcnt'length);
159
                        else
160
                            -- EOP or EEP
161
                            v.out_data  := r.parity;
162
                            v.bitshift(1) := xmiti.txdata(0);
163
                            v.bitshift(2) := not xmiti.txdata(0);
164
                            v.bitcnt    := to_unsigned(3, v.bitcnt'length);
165
                        end if;
166
                    else
167
                        -- Send NULL.
168
                        v.out_data  := r.parity;
169
                        v.bitshift(6 downto 0) := "0010111";
170
                        v.bitcnt    := to_unsigned(7, v.bitcnt'length);
171
                        v.parity    := '0';
172
                        v.sent_null := '1';
173
                    end if;
174
 
175
                else
176
 
177
                    -- Shift next bit to the output.
178
                    v.out_data  := r.bitshift(0);
179
                    v.parity    := r.parity xor r.bitshift(0);
180
                    v.bitshift(r.bitshift'high-1 downto 0) := r.bitshift(r.bitshift'high downto 1);
181
                    v.bitcnt    := r.bitcnt - 1;
182
 
183
                end if;
184
 
185
                -- Data-Strobe encoding.
186
                v.out_strobe := not (r.out_strobe xor r.out_data xor v.out_data);
187
 
188
            end if;
189
 
190
            -- Store requests for time tick transmission.
191
            if xmiti.tick_in = '1' then
192
                v.pend_tick := '1';
193
                v.pend_time := xmiti.ctrl_in & xmiti.time_in;
194
            end if;
195
 
196
        end if;
197
 
198
        -- Synchronous reset
199
        if rst = '1' then
200
            v := regs_reset;
201
        end if;
202
 
203
        -- Drive outputs.
204
        -- Note: the outputs are combinatorially dependent on certain inputs.
205
 
206
        -- Set fctack high if (transmitter enabled) AND
207
        -- (ready for token) AND (FCTs allowed) AND
208
        -- ((characters not allowed) OR (no timecode pending)) AND
209
        -- (FCT requested)
210
        if (xmiti.txen = '1') and
211
           (r.txclken = '1') and (r.bitcnt = 0) and (r.allow_fct = '1') and
212
           ((r.allow_char = '0') or (r.pend_tick = '0')) then
213
            xmito.fctack  <= xmiti.fct_in;
214
        else
215
            xmito.fctack  <= '0';
216
        end if;
217
 
218
        -- Set txrdy high if (transmitter enabled) AND
219
        -- (ready for token) AND (characters enabled) AND
220
        -- (no timecode pending) AND (no FCT requested) AND
221
        -- (character requested)
222
        if (xmiti.txen = '1') and
223
           (r.txclken = '1') and (r.bitcnt = 0) and (r.allow_char = '1') and
224
           (r.pend_tick = '0') and (xmiti.fct_in = '0') then
225
            xmito.txack   <= xmiti.txwrite;
226
        else
227
            xmito.txack   <= '0';
228
        end if;
229
 
230
        -- Update registers
231
        rin <= v;
232
    end process;
233
 
234
    -- Synchronous process
235
    process (clk) is
236
    begin
237
        if rising_edge(clk) then
238
 
239
            -- Update registers
240
            r <= rin;
241
 
242
            -- Drive spacewire output signals
243
            spw_do  <= r.out_data;
244
            spw_so  <= r.out_strobe;
245
 
246
        end if;
247
    end process;
248
 
249
end architecture spwxmit_arch;

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.