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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_sdlc_if.vhd] - Blame information for rev 278

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 192 jshamlet
-- Copyright (c)2020 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
--
24
-- VHDL Units :  o8_sdlc_if
25
-- Description:  Provides a full memory-mapped SDLC stack with automatic CRC16
26 273 jshamlet
--                Checksum insertion and integrity checking. Note that this
27
--                entity ONLY provides packet framing and checksum calculation.
28 192 jshamlet
--
29
-- Transmit Memory Map
30
-- "0_0000_0000" (0x000) TX Buffer START
31
-- "0_1111_1101" (0x0FD) TX Buffer END
32
-- "0_1111_1110" (0x0FE) Clock Status*
33
-- "0_1111_1111" (0x0FF) TX Length / Status**
34
--
35
-- Receive Memory Map
36
-- "1_0000_0000" (0x100) RX Buffer START
37 196 jshamlet
-- "1_1111_1101" (0x1FD) RX Buffer END
38 201 jshamlet
-- "1_1111_1110" (0x0FE) RX Checksum Status***
39
-- "1_1111_1111" (0x1FF) RX Length   Status****
40 192 jshamlet
--
41 201 jshamlet
-- *    Address 0xFE reports the SDLC bit clock status and updates on changes.
42
--      1) If BClk_Okay = '0' (Bitclock is NOT present), the field will report
43
--          0x00. Otherwise, it will report 0xFF if the bitclock is present.
44
--      2) Writing any value to the register will cause the controller to
45
--         silently reset the clock status without causing an interrupt.
46 199 jshamlet
--
47 201 jshamlet
-- **   This location serves as the control/status register for transmit
48
--      1) Writing a value between 1 and 253 will trigger the transmit engine,
49
--          using the write value as the packet length.
50
--      2) Values 0x00, 0xFE, or 0xFF are invalid, and will be ignored.
51
--      3) This value will change from the user written value to 0xFF once the
52
--          packet is transmitted to indicate the transmission is complete.
53 199 jshamlet
--
54 201 jshamlet
-- ***  This location serves as the status register for receive checksum test
55
--      1) A value of 0x00 indicates the CRC did NOT match, while a value
56
--         of 0xFF indicates that the recieved CRC matches the calculated CRC.
57
--
58
-- **** This location serves as the status register for the receive
59
--      1) This value is only updated on reception of a full frame, indicated
60
--          by a start followed by a stop flag. Incomplete frames are ignored.
61 204 jshamlet
--      2) If too many bytes are received (buffer overflow), a value of
62 201 jshamlet
--          ERR_LENGTH is written.
63 224 jshamlet
--
64
-- Revision History
65
-- Author          Date     Change
66
------------------ -------- ---------------------------------------------------
67 278 jshamlet
-- Seth Henry      12/09/20 Created from merged sub-entities into flat file
68 192 jshamlet
 
69
library ieee;
70
  use ieee.std_logic_1164.all;
71
  use ieee.std_logic_unsigned.all;
72
  use ieee.std_logic_arith.all;
73 278 jshamlet
  use ieee.std_logic_misc.all;
74 192 jshamlet
 
75
library work;
76
  use work.open8_pkg.all;
77
 
78
entity o8_sdlc_if is
79
generic(
80
  Poly_Init                  : std_logic_vector(15 downto 0) := x"0000";
81
  Set_As_Master              : boolean := true;
82
  Clock_Offset               : integer := 6;
83 224 jshamlet
  BitClock_Frequency         : real := 500000.0;
84
  Clock_Frequency            : real := 100000000.0;
85 192 jshamlet
  Address                    : ADDRESS_TYPE
86
);
87
port(
88 223 jshamlet
  Open8_Bus                  : in  OPEN8_BUS_TYPE;
89 244 jshamlet
  Write_Qual                 : in  std_logic := '1';
90 192 jshamlet
  Rd_Data                    : out DATA_TYPE;
91 263 jshamlet
  TX_Interrupt               : out std_logic;
92
  RX_Interrupt               : out std_logic;
93 192 jshamlet
  -- Serial IO
94
  SDLC_In                    : in  std_logic;
95
  SDLC_SClk                  : in  std_logic;
96
  SDLC_MClk                  : out std_logic;
97
  SDLC_Out                   : out std_logic
98
);
99
end entity;
100
 
101
architecture behave of o8_sdlc_if is
102
 
103 278 jshamlet
  -- convenient subtypes & constants
104
  subtype CRC_TYPE           is std_logic_vector(15 downto 0);
105
 
106
  -- Bus interface
107 224 jshamlet
  alias Clock                is Open8_Bus.Clock;
108
  alias Reset                is Open8_Bus.Reset;
109
 
110 192 jshamlet
  constant Base_Addr         : std_logic_vector(15 downto 9)
111
                               := Address(15 downto 9);
112
 
113 223 jshamlet
  alias CPU_Upper_Addr       is Open8_Bus.Address(15 downto 9);
114 205 jshamlet
  signal Base_Addr_Match     : std_logic := '0';
115 192 jshamlet
 
116 244 jshamlet
  alias  DP_A_Addr           is Open8_Bus.Address(8 downto 0);
117 205 jshamlet
  signal DP_A_Wr_En          : std_logic := '0';
118 223 jshamlet
  alias  DP_A_Wr_Data        is Open8_Bus.Wr_Data;
119 244 jshamlet
  signal DP_A_Rd_En_d        : std_logic := '0';
120
  signal DP_A_Rd_En_q        : std_logic := '0';
121 205 jshamlet
  signal DP_A_Rd_Data        : DATA_TYPE := OPEN8_NULLBUS;
122 192 jshamlet
 
123 196 jshamlet
  constant Reg_Sub_Addr      : std_logic_vector(8 downto 1) := x"7F";
124 223 jshamlet
  alias Reg_Upper_Addr       is Open8_Bus.Address(8 downto 1);
125
  alias Reg_Lower_Addr       is Open8_Bus.Address(0);
126 196 jshamlet
 
127
  signal Reg_Addr            : std_logic_vector(8 downto 1) := (others => '0');
128 278 jshamlet
  signal Reg_Sel             : std_logic := '0';
129
  signal Reg_Wr_En_d         : std_logic := '0';
130
  signal Reg_Wr_En_q         : std_logic := '0';
131
  signal TX_Ctl_Clk          : std_logic := '0';
132
  signal TX_Ctl_Len          : std_logic := '0';
133 196 jshamlet
 
134 278 jshamlet
  -- Dual-port memory
135
  signal DP_Addr             : std_logic_vector(8 downto 0);
136
  signal DP_Wr_Data          : DATA_TYPE;
137
  signal DP_Wr_En            : std_logic;
138
  signal DP_Rd_Data          : DATA_TYPE;
139 192 jshamlet
 
140 278 jshamlet
  alias  DP_B_Addr           is DP_Addr;
141
  alias  DP_B_Wr_Data        is DP_Wr_Data;
142
  alias  DP_B_Wr_En          is DP_Wr_En;
143
  alias  DP_B_Rd_Data        is DP_Rd_Data;
144 202 jshamlet
 
145 278 jshamlet
  -- Internal definitions
146
  constant SDLC_Flag         : DATA_TYPE := x"7E";
147 202 jshamlet
 
148 278 jshamlet
  constant CK_REGISTER       : DATA_TYPE := x"FE";
149
  constant TX_REGISTER       : DATA_TYPE := x"FF";
150
  constant CS_REGISTER       : DATA_TYPE := x"FE";
151
  constant RX_REGISTER       : DATA_TYPE := x"FF";
152 192 jshamlet
 
153 278 jshamlet
  constant TX_RESERVED_LOW   : integer := 0;
154
  constant TX_RESERVED_HIGH  : integer := 254;
155 192 jshamlet
 
156 278 jshamlet
  constant FLAG_DONE         : DATA_TYPE := x"FF";
157 192 jshamlet
 
158 278 jshamlet
  constant ERR_LENGTH        : DATA_TYPE := x"00";
159 192 jshamlet
 
160 278 jshamlet
  -- RAM Arbitration logic
161
  type DP_ARB_STATES is (PAUSE, IDLE,
162
                         PORT0_AD, PORT0_WR, PORT0_RD0, PORT0_RD1,
163
                         PORT1_AD, PORT1_WR, PORT1_RD0, PORT1_RD1  );
164
  signal DP_Arb_State        : DP_ARB_STATES := IDLE;
165
  signal DP_Last_Port        : std_logic := '0';
166 192 jshamlet
 
167 278 jshamlet
  signal DP_Port0_Addr       : DATA_TYPE := x"00";
168
  signal DP_Port0_RWn        : std_logic := '0';
169
  signal DP_Port0_WrData     : DATA_TYPE := x"00";
170
  signal DP_Port0_RdData     : DATA_TYPE := x"00";
171
  signal DP_Port0_Req        : std_logic := '0';
172
  signal DP_Port0_Ack        : std_logic := '0';
173 202 jshamlet
 
174 278 jshamlet
  signal DP_Port1_Addr       : DATA_TYPE := x"00";
175
  signal DP_Port1_RWn        : std_logic := '0';
176
  signal DP_Port1_WrData     : DATA_TYPE := x"00";
177
  signal DP_Port1_RdData     : DATA_TYPE := x"00";
178
  signal DP_Port1_Req        : std_logic := '0';
179
  signal DP_Port1_Ack        : std_logic := '0';
180
 
181
-- Clock generation
182
  constant DLY_VAL           : integer := integer(Clock_Frequency / (2.0 * BitClock_Frequency) );
183
  constant DLY_WDT           : integer := ceil_log2(DLY_VAL - 1);
184
  constant DLY_VEC           : std_logic_vector :=
185
                               conv_std_logic_vector( DLY_VAL - 1, DLY_WDT);
186
  signal BClk_Cntr           : std_logic_vector( DLY_WDT - 1 downto 0 ) := (others => '0');
187
 
188
  signal BClk_Adv            : std_logic := '0';
189
  signal BClk_Accum          : std_logic_vector(31 downto 0) := (others => '0');
190
  signal BClk_Div            : std_logic := '0';
191
  signal BClk_Okay_SR        : std_logic_vector(3 downto 0)  := (others => '0');
192
 
193
 
194
  signal BClk_SR             : std_logic_vector(2 downto 0)  := (others => '0');
195
 
196
  constant CLK_RATIO_R       : real := Clock_Frequency / (1.0 * BitClock_Frequency);
197
  constant CLK_DEVIATION_5P  : real := CLK_RATIO_R * 0.05;
198
  constant CLK_RATIO_ADJ_R   : real := CLK_RATIO_R + CLK_DEVIATION_5P;
199
  constant CLK_RATIO_ADJ_I   : integer := integer(CLK_RATIO_ADJ_R);
200
 
201
  constant Threshold_bits    : integer := ceil_log2(CLK_RATIO_ADJ_I);
202
  constant THRESHOLD         : std_logic_vector(Threshold_bits - 1 downto 0) :=
203
                        conv_std_logic_vector(CLK_RATIO_ADJ_I,Threshold_bits);
204
 
205
  signal RE_Threshold_Ctr    : std_logic_vector(Threshold_Bits - 1 downto 0) :=
206
                                (others => '0');
207
  signal FE_Threshold_Ctr    : std_logic_vector(Threshold_Bits - 1 downto 0) :=
208
                                (others => '0');
209
 
210
  signal Ref_In_SR           : std_logic_vector(2 downto 0) := (others => '0');
211
  alias  Ref_In_q1           is Ref_In_SR(1);
212
  alias  Ref_In_q2           is Ref_In_SR(2);
213
  signal Ref_In_RE           : std_logic := '0';
214
  signal Ref_In_FE           : std_logic := '0';
215
 
216
  signal BClk_RE             : std_logic := '0';
217
  signal BClk_FE             : std_logic := '0';
218
  signal BClk_Okay           : std_logic := '0';
219
 
220
-- Packet Transmit state logic
221
  type TX_FSM_STATES is ( INIT_FLAG,
222
                          WR_CLOCK_STATE, WAIT_FOR_CLOCK,
223
                          WAIT_FOR_UPDATE,
224
                          RD_TX_REGISTER, TX_INIT,
225
                          TX_START_FLAG, TX_WAIT_START_FLAG,
226
                          TX_MESG_DATA, TX_ADV_ADDR, TX_WAIT_MESG_DATA,
227
                          TX_CRC_LB_WR, TX_CRC_LB_WAIT,
228
                          TX_CRC_UB_WR, TX_CRC_UB_WAIT,
229
                          TX_STOP_FLAG, TX_WAIT_STOP_FLAG, TX_SET_FLAG );
230
 
231
  signal TX_FSM_State        : TX_FSM_STATES := WR_CLOCK_STATE;
232
  signal TX_Length           : DATA_TYPE := x"00";
233
 
234
  signal BClk_q1, BClk_CoS   : std_logic := '0';
235
  signal TX_Int_pend         : std_logic := '0';
236
 
237
  signal TX_Wr_En            : std_logic := '0';
238
  signal TX_Wr_Flag          : std_logic := '0';
239
  signal TX_Wr_Data          : DATA_TYPE := x"00";
240
  signal TX_Req_Next         : std_logic := '0';
241
 
242
  signal TX_CRC_Clr          : std_logic := '0';
243
  signal TX_CRC_En           : std_logic := '0';
244
  signal TX_CRC_Data         : CRC_TYPE  := x"0000";
245
  signal TX_CRC_Valid        : std_logic := '0';
246
 
247
  alias  TX_CRC_Data_LB      is TX_CRC_Data(7 downto 0);
248
  alias  TX_CRC_Data_UB      is TX_CRC_Data(15 downto 8);
249
 
250
  signal TX_Arm              : std_logic := '0';
251
  signal TX_Flag             : std_logic := '0';
252
  signal TX_Buffer           : std_logic_vector(8 downto 0) := (others => '0');
253
  alias  TX_Buffer_Flag      is TX_Buffer(8);
254
  alias  TX_Buffer_Data      is TX_Buffer(7 downto 0);
255
 
256
-- SDLC transmitter
257
  type TX_STATES is (INIT, IDLE, XMIT, SPACE, TERM, LD_NEXT);
258
  signal TX_State            : TX_STATES := INIT;
259
 
260
  signal TX_ShftReg          : DATA_TYPE := (others => '0');
261
  signal TX_Next             : std_logic := '0';
262
  signal TX_BitStuff         : std_logic_vector(4 downto 0) := (others => '0');
263
  signal TX_BitCntr          : std_logic_vector(3 downto 0) := (others => '0');
264
  alias  TX_BitSel           is TX_BitCntr(2 downto 0);
265
  alias  TX_Term             is TX_BitCntr(3);
266
 
267
-- SDLC receiver
268
  signal RX_LatchEn_SR       : std_logic_vector(Clock_Offset downto 0) := (others => '0');
269
  alias  RX_LatchEn_M        is RX_LatchEn_SR(Clock_Offset);
270
  alias  RX_LatchEn_S        is BClk_RE;
271
  signal RX_LatchEn          : std_logic := '0';
272
 
273
  signal RX_Serial_SR        : std_logic_vector(1 downto 0) := (others => '0');
274
  alias  RX_Serial           is RX_Serial_SR(1);
275
 
276
  type RX_STATES is (INIT, IDLE, RCV_DATA, SKIP_ZERO, WRITE_DATA);
277
  signal RX_State            : RX_STATES := INIT;
278
  signal RX_Buffer           : DATA_TYPE := x"00";
279
  signal RX_BitStuff_SR      : std_logic_vector(4 downto 0) := (others => '0');
280
  signal RX_BitCntr          : std_logic_vector(3 downto 0) := (others => '0');
281
  alias  RX_BitSel           is RX_BitCntr(2 downto 0);
282
  alias  RX_Term             is RX_BitCntr(3);
283
 
284
  signal RX_Flag_SR          : DATA_TYPE := x"00";
285
 
286
  signal RX_Idle_Cntr        : std_logic_vector(2 downto 0) := (others => '0');
287
 
288
  signal RX_Valid            : std_logic := '0';
289
  signal RX_Flag             : std_logic := '0';
290
  signal RX_Data             : DATA_TYPE := x"00";
291
  signal RX_Idle             : std_logic := '0';
292
 
293
-- Packet detection logic
294
  type PACKET_STATES is (IDLE, FRAME_START, FRAME_DATA, FRAME_STOP );
295
  signal Pkt_State           : PACKET_STATES := IDLE;
296
  signal First_Byte          : std_logic := '0';
297
 
298
  signal RX_Frame_Start      : std_logic := '0';
299
  signal RX_Frame_Stop       : std_logic := '0';
300
  signal RX_Frame_Valid      : std_logic := '0';
301
  signal RX_Frame_Data       : DATA_TYPE := x"00";
302
 
303
-- Receive data CRC calculation
304
  signal RX_CRC_Valid        : std_logic := '0';
305
  signal RX_CRC_Data         : CRC_TYPE  := x"0000";
306
 
307
  type CRC_HISTORY is array(0 to 2) of CRC_TYPE;
308
  signal RX_CRC_Hist         : CRC_HISTORY := (x"0000",x"0000",x"0000");
309
  alias  RX_CRC_Calc         is RX_CRC_Hist(2);
310
 
311
  signal RX_CRC_Rcvd         : CRC_TYPE  := x"0000";
312
  alias  RX_CRC_Rcvd_LB      is RX_CRC_Rcvd(7 downto 0);
313
  alias  RX_CRC_Rcvd_UB      is RX_CRC_Rcvd(15 downto 8);
314
 
315
-- Packet receive state logic
316
  type RX_FSM_STATES is ( WAIT_FOR_CLOCK, WAIT_FOR_FLAG,
317
                          RX_MESG_DATA, RX_WR_DATA,
318
                          RX_CRC_LB_RD, RX_CRC_UB_RD,
319
                          RX_WR_CRC, RX_WR_COUNT );
320
 
321
  signal RX_FSM_State        : RX_FSM_STATES := WAIT_FOR_CLOCK;
322
 
323
  signal RX_Length           : DATA_TYPE := x"00";
324
 
325 192 jshamlet
begin
326 278 jshamlet
 
327
-- ***************************************************************************
328
-- *          Open8 Bus Interface and Control Register Detection             *
329
-- ***************************************************************************
330
 
331
  -- This decode needs to happen immediately, to give the RAM a chance to
332
  --  do the lookup before we have to set Rd_Data
333
  Base_Addr_Match            <= '1' when Base_Addr = CPU_Upper_Addr else '0';
334
  Reg_Wr_En_d                <= Base_Addr_Match and
335
                                Open8_Bus.Wr_En and
336
                                Write_Qual;
337
 
338
  DP_A_Wr_En                 <= Base_Addr_Match and
339
                                Open8_Bus.Wr_En and
340
                                Write_Qual;
341
 
342
  DP_A_Rd_En_d               <= Base_Addr_Match and Open8_Bus.Rd_En;
343
 
344
  CPU_IF_proc: process( Reset, Clock )
345
  begin
346
    if( Reset = Reset_Level )then
347
      Reg_Addr               <= (others => '0');
348
      Reg_Wr_En_q            <= '0';
349
      TX_Ctl_Clk             <= '0';
350
      TX_Ctl_Len             <= '0';
351
      DP_A_Rd_En_q           <= '0';
352
      Rd_Data                <= OPEN8_NULLBUS;
353
    elsif( rising_edge(Clock) )then
354
      Reg_Addr               <= Reg_Upper_Addr;
355
      Reg_Sel                <= Reg_Lower_Addr;
356
      Reg_Wr_En_q            <= Reg_Wr_En_d;
357
 
358
      TX_Ctl_Clk             <= '0';
359
      TX_Ctl_Len             <= '0';
360
      if( Reg_Addr = Reg_Sub_Addr )then
361
        TX_Ctl_Clk           <= Reg_Wr_En_q and not Reg_Sel;
362
        TX_Ctl_Len           <= Reg_Wr_En_q and Reg_Sel;
363
      end if;
364
 
365
      DP_A_Rd_En_q           <= DP_A_Rd_En_d;
366
      Rd_Data                <= OPEN8_NULLBUS;
367
      if( DP_A_Rd_En_q = '1' )then
368
        Rd_Data              <= DP_A_Rd_Data;
369
      end if;
370
    end if;
371
  end process;
372
 
373
-- ***************************************************************************
374
-- *                     Shared Dual-Port Memory                             *
375
-- ***************************************************************************
376
 
377
  U_RAM : entity work.sdlc_dp512b_ram
378
  port map(
379
    clock                    => Clock,
380
    address_a                => DP_A_Addr,
381
    address_b                => DP_B_Addr,
382
    data_a                   => DP_A_Wr_Data,
383
    data_b                   => DP_B_Wr_Data,
384
    wren_a                   => DP_A_Wr_En,
385
    wren_b                   => DP_B_Wr_En,
386
    q_a                      => DP_A_Rd_Data,
387
    q_b                      => DP_B_Rd_Data
388
  );
389
 
390 202 jshamlet
-- ***************************************************************************
391 278 jshamlet
-- *                     Memory Arbitration                                  *
392 202 jshamlet
-- ***************************************************************************
393
 
394 278 jshamlet
  RAM_Arbitration_proc: process( Clock, Reset )
395
  begin
396
    if( Reset = Reset_Level )then
397
      DP_Arb_State           <= IDLE;
398
      DP_Last_Port           <= '0';
399
      DP_Addr                <= (others => '0');
400
      DP_Wr_Data             <= x"00";
401
      DP_Wr_En               <= '0';
402
      DP_Port0_RdData        <= x"00";
403
      DP_Port0_Ack           <= '0';
404
      DP_Port1_RdData        <= x"00";
405
      DP_Port1_Ack           <= '0';
406
    elsif( rising_edge(Clock) )then
407
      DP_Port0_Ack           <= '0';
408
      DP_Port1_Ack           <= '0';
409
      DP_Wr_En               <= '0';
410 192 jshamlet
 
411 278 jshamlet
      case( DP_Arb_State )is
412
        when IDLE =>
413
          if( DP_Port0_Req = '1' and (DP_Port1_Req = '0' or DP_Last_Port = '1') )then
414
            DP_Arb_State     <= PORT0_AD;
415
          elsif( DP_Port1_Req = '1' and (DP_Port0_Req = '0' or DP_Last_Port = '0') )then
416
            DP_Arb_State     <= PORT1_AD;
417
          end if;
418 244 jshamlet
 
419 278 jshamlet
        when PORT0_AD =>
420
          DP_Last_Port       <= '0';
421
          DP_Addr            <= '0' & DP_Port0_Addr;
422
          DP_Wr_Data         <= DP_Port0_WrData;
423
          DP_Wr_En           <= not DP_Port0_RWn;
424
          if( DP_Port0_RWn = '1' )then
425
            DP_Arb_State     <= PORT0_RD0;
426
          else
427
            DP_Port0_Ack     <= '1';
428
            DP_Arb_State     <= PORT0_WR;
429
          end if;
430 244 jshamlet
 
431 278 jshamlet
        when PORT0_WR =>
432
          DP_Arb_State       <= IDLE;
433
 
434
        when PORT0_RD0 =>
435
          DP_Arb_State       <= PORT0_RD1;
436
 
437
        when PORT0_RD1 =>
438
          DP_Port0_Ack       <= '1';
439
          DP_Port0_RdData    <= DP_Rd_Data;
440
          DP_Arb_State       <= PAUSE;
441
 
442
        when PORT1_AD =>
443
          DP_Last_Port       <= '1';
444
          DP_Addr            <= '1' & DP_Port1_Addr;
445
          DP_Wr_Data         <= DP_Port1_WrData;
446
          DP_Wr_En           <= not DP_Port1_RWn;
447
          if( DP_Port0_RWn = '1' )then
448
            DP_Arb_State     <= PORT1_RD0;
449
          else
450
            DP_Port1_Ack     <= '1';
451
            DP_Arb_State     <= PORT1_WR;
452
          end if;
453
 
454
        when PORT1_WR =>
455
          DP_Arb_State       <= IDLE;
456
 
457
        when PORT1_RD0 =>
458
          DP_Arb_State       <= PORT1_RD1;
459
 
460
        when PORT1_RD1 =>
461
          DP_Port1_Ack       <= '1';
462
          DP_Port1_RdData    <= DP_Rd_Data;
463
          DP_Arb_State       <= PAUSE;
464
 
465
        when PAUSE =>
466
          DP_Arb_State       <= IDLE;
467
 
468
        when others => null;
469
 
470
      end case;
471
    end if;
472
  end process;
473
 
474
-- ****************************************************************************
475
-- * Bit clock generation                                                     *
476
-- ****************************************************************************
477
 
478
Clock_Master: if( Set_As_Master )generate
479
 
480
  Clock_Gen_proc: process( Clock, Reset )
481 192 jshamlet
  begin
482
    if( Reset = Reset_Level )then
483 278 jshamlet
      BClk_Cntr              <= DLY_VEC;
484
      BClk_Adv               <= '0';
485
      BClk_Accum             <= (others => '0');
486
      BClk_Div               <= '0';
487
      BClk_Okay_SR           <= (others => '0');
488
      BClk_RE                <= '0';
489
      BClk_FE                <= '0';
490
      SDLC_MClk              <= '0';
491
    elsif( rising_edge( Clock ) )then
492
      BClk_Cntr              <= BClk_Cntr - 1;
493
      BClk_Adv               <= '0';
494
      if( or_reduce(BClk_Cntr) = '0' )then
495
        BClk_Cntr            <= DLY_VEC;
496
        BClk_Adv             <= '1';
497
        BClk_Okay_SR         <= BClk_Okay_SR(2 downto 0) & '1';
498
      end if;
499
      BClk_Accum             <= BClk_Accum + BClk_Adv;
500
      BClk_Div               <= BClk_Div xor BClk_Adv;
501
      BClk_RE                <= (not BClk_Div) and BClk_Adv;
502
      BClk_FE                <= BClk_Div and BClk_Adv;
503
      SDLC_MClk              <= BClk_Div;
504
    end if;
505
  end process;
506
 
507
  BClk_Okay                  <= BClk_Okay_SR(3);
508
 
509
end generate;
510
 
511
Clock_Slave: if( not Set_As_Master )generate
512
 
513
  Clock_Edge_proc: process( Clock, Reset )
514
  begin
515
    if( Reset = Reset_Level )then
516
      BClk_SR                <= (others => '0');
517
      BClk_FE                <= '0';
518
      BClk_RE                <= '0';
519 192 jshamlet
    elsif( rising_edge(Clock) )then
520 278 jshamlet
      BClk_SR                <= BClk_SR(1 downto 0) & SDLC_SClk;
521
      BClk_FE                <= BClk_SR(2) and (not BClk_SR(1));
522
      BClk_RE                <= (not BClk_SR(2)) and BClk_SR(1);
523
    end if;
524
  end process;
525 192 jshamlet
 
526 278 jshamlet
  SDLC_MClk                  <= '0';
527
 
528
  Clock_Detect_proc: process( Clock, Reset )
529
  begin
530
    if( Reset = Reset_Level )then
531
      Ref_In_SR              <= (others => '0');
532
      Ref_In_RE              <= '0';
533
      Ref_In_FE              <= '0';
534
      RE_Threshold_Ctr       <= (others => '0');
535
      FE_Threshold_Ctr       <= (others => '0');
536
      BClk_Okay              <= '0';
537
 
538
    elsif( rising_edge(Clock) )then
539
      Ref_In_SR              <= Ref_In_SR(1 downto 0) & SDLC_SClk;
540
      Ref_In_RE              <= Ref_In_q1 and (not Ref_In_q2);
541
      Ref_In_FE              <= (not Ref_In_q1) and Ref_In_q2;
542
 
543
      RE_Threshold_Ctr       <= RE_Threshold_Ctr - 1;
544
      if( Ref_In_RE = '1' )then
545
        RE_Threshold_Ctr     <= THRESHOLD;
546
      elsif( or_reduce(RE_Threshold_Ctr) = '0' )then
547
        RE_Threshold_Ctr     <= (others => '0');
548 192 jshamlet
      end if;
549
 
550 278 jshamlet
      FE_Threshold_Ctr       <= FE_Threshold_Ctr - 1;
551
      if( Ref_In_FE = '1' )then
552
        FE_Threshold_Ctr     <= THRESHOLD;
553
      elsif( or_reduce(FE_Threshold_Ctr) = '0' )then
554
        FE_Threshold_Ctr     <= (others => '0');
555 192 jshamlet
      end if;
556 278 jshamlet
 
557
 
558
      BClk_Okay              <= or_reduce(RE_Threshold_Ctr) and
559
                                or_reduce(FE_Threshold_Ctr);
560
 
561 192 jshamlet
    end if;
562
  end process;
563
 
564 278 jshamlet
end generate;
565
 
566 202 jshamlet
-- ***************************************************************************
567 278 jshamlet
-- *                     Serial Transmit Path                                *
568 202 jshamlet
-- ***************************************************************************
569
 
570 278 jshamlet
  TX_Packet_RAM_proc: process( Reset, Clock )
571
  begin
572
    if( Reset = Reset_Level )then
573
      TX_FSM_State           <= INIT_FLAG;
574 192 jshamlet
 
575 278 jshamlet
      DP_Port0_Addr          <= x"00";
576
      DP_Port0_RWn           <= '1';
577
      DP_Port0_WrData        <= x"00";
578
      DP_Port0_Req           <= '0';
579 202 jshamlet
 
580 278 jshamlet
      TX_Length              <= x"00";
581 202 jshamlet
 
582 278 jshamlet
      TX_Wr_En               <= '0';
583
      TX_Wr_Flag             <= '0';
584
      TX_Wr_Data             <= x"00";
585 202 jshamlet
 
586 278 jshamlet
      TX_CRC_Clr             <= '0';
587
      TX_CRC_En              <= '0';
588 192 jshamlet
 
589 278 jshamlet
      BClk_q1                <= '0';
590
      BClk_CoS               <= '0';
591 202 jshamlet
 
592 278 jshamlet
      TX_Int_pend            <= '0';
593
      TX_Interrupt           <= '0';
594 202 jshamlet
 
595 278 jshamlet
    elsif( rising_edge(Clock) )then
596
 
597
      DP_Port0_RWn           <= '1';
598
      DP_Port0_WrData        <= x"00";
599
      DP_Port0_Req           <= '0';
600
 
601
      TX_Wr_En               <= '0';
602
      TX_Wr_Flag             <= '0';
603
      TX_Wr_Data             <= x"00";
604
 
605
      TX_CRC_Clr             <= '0';
606
      TX_CRC_En              <= '0';
607
 
608
      BClk_q1                <= BClk_Okay;
609
      BClk_CoS               <= BClk_q1 xor BClk_Okay;
610
 
611
      TX_Interrupt           <= '0';
612
 
613
      case( TX_FSM_State )is
614
 
615
        when INIT_FLAG =>
616
          DP_Port0_Addr      <= TX_REGISTER;
617
          DP_Port0_Req       <= '1';
618
          DP_Port0_WrData    <= FLAG_DONE;
619
          DP_Port0_RWn       <= '0';
620
          if( DP_Port0_Ack = '1' )then
621
            DP_Port0_Req     <= '0';
622
            TX_FSM_State     <= WR_CLOCK_STATE;
623
          end if;
624
 
625
        when WAIT_FOR_UPDATE =>
626
          if( TX_Ctl_Clk = '1' )then
627
            TX_FSM_State     <= WR_CLOCK_STATE;
628
          end if;
629
          if( TX_Ctl_Len = '1' )then
630
            TX_FSM_State     <= RD_TX_REGISTER;
631
          end if;
632
 
633
        when WR_CLOCK_STATE =>
634
          DP_Port0_Addr      <= CK_REGISTER;
635
          DP_Port0_Req       <= '1';
636
          DP_Port0_WrData    <= (others => BClk_Okay);
637
          DP_Port0_RWn       <= '0';
638
          if( DP_Port0_Ack = '1' )then
639
            TX_Interrupt     <= TX_Int_pend;
640
            TX_Int_pend      <= '0';
641
            DP_Port0_Req     <= '0';
642
            TX_FSM_State     <= WAIT_FOR_CLOCK;
643
          end if;
644
 
645
        when WAIT_FOR_CLOCK =>
646
          if( BClk_Okay = '1' )then
647
            TX_FSM_State     <= WAIT_FOR_UPDATE;
648
          end if;
649
 
650
        when RD_TX_REGISTER =>
651
          DP_Port0_Addr      <= TX_REGISTER;
652
          DP_Port0_Req       <= '1';
653
          if( DP_Port0_Ack = '1' )then
654
            DP_Port0_Req     <= '0';
655
            TX_Length        <= DP_Port0_RdData;
656
            TX_FSM_State     <= TX_INIT;
657
          end if;
658
 
659
        when TX_INIT =>
660
          TX_FSM_State       <= WAIT_FOR_UPDATE;
661
          if( TX_Length > TX_RESERVED_LOW and
662
              TX_Length < TX_RESERVED_HIGH )then
663
            TX_CRC_Clr       <= '1';
664
            TX_FSM_State     <= TX_START_FLAG;
665
          end if;
666
 
667
        when TX_START_FLAG =>
668
          TX_Wr_En           <= '1';
669
          TX_Wr_Flag         <= '1';
670
          TX_Wr_Data         <= SDLC_FLAG;
671
          TX_FSM_State       <= TX_WAIT_START_FLAG;
672
 
673
        when TX_WAIT_START_FLAG =>
674
          if( TX_Req_Next = '1' )then
675
            DP_Port0_Addr    <= x"00";
676
            TX_FSM_State     <= TX_ADV_ADDR;
677
          end if;
678
 
679
        when TX_ADV_ADDR =>
680
          DP_Port0_Req       <= '1';
681
          if( DP_Port0_Ack = '1' )then
682
            DP_Port0_Req     <= '0';
683
            DP_Port0_Addr    <= DP_Port0_Addr + 1;
684
            TX_Length        <= TX_Length - 1;
685
            TX_FSM_State     <= TX_MESG_DATA;
686
          end if;
687
 
688
        when TX_MESG_DATA =>
689
          TX_Wr_En           <= '1';
690
          TX_Wr_Data         <= DP_Port0_RdData;
691
          TX_CRC_En          <= '1';
692
          TX_FSM_State       <= TX_WAIT_MESG_DATA;
693
 
694
        when TX_WAIT_MESG_DATA =>
695
          if( TX_Req_Next = '1' )then
696
            TX_FSM_State     <= TX_ADV_ADDR;
697
            if( TX_Length = 0 )then
698
              TX_FSM_State   <= TX_CRC_LB_WR;
699
            end if;
700
          end if;
701
 
702
        when TX_CRC_LB_WR =>
703
          TX_Wr_En           <= '1';
704
          TX_Wr_Data         <= TX_CRC_Data_LB;
705
          TX_FSM_State       <= TX_CRC_LB_WAIT;
706
 
707
        when TX_CRC_LB_WAIT =>
708
          if( TX_Req_Next = '1' )then
709
              TX_FSM_State   <= TX_CRC_UB_WR;
710
          end if;
711
 
712
        when TX_CRC_UB_WR =>
713
          TX_Wr_En           <= '1';
714
          TX_Wr_Data         <= TX_CRC_Data_UB;
715
          TX_FSM_State       <= TX_CRC_UB_WAIT;
716
 
717
        when TX_CRC_UB_WAIT =>
718
          if( TX_Req_Next = '1' )then
719
              TX_FSM_State   <= TX_STOP_FLAG;
720
          end if;
721
 
722
        when TX_STOP_FLAG =>
723
          TX_Wr_En           <= '1';
724
          TX_Wr_Flag         <= '1';
725
          TX_Wr_Data         <= SDLC_FLAG;
726
          TX_FSM_State       <= TX_WAIT_STOP_FLAG;
727
 
728
        when TX_WAIT_STOP_FLAG =>
729
          if( TX_Req_Next = '1' )then
730
            TX_FSM_State     <= TX_SET_FLAG;
731
          end if;
732
 
733
        when TX_SET_FLAG =>
734
          DP_Port0_Addr      <= TX_REGISTER;
735
          DP_Port0_Req       <= '1';
736
          DP_Port0_WrData    <= FLAG_DONE;
737
          DP_Port0_RWn       <= '0';
738
          if( DP_Port0_Ack = '1' )then
739
            DP_Port0_Req     <= '0';
740
            TX_FSM_State     <= WAIT_FOR_UPDATE;
741
          end if;
742
 
743
        when others => null;
744
      end case;
745
 
746
      if( BClk_CoS = '1' )then
747
        TX_Int_pend          <= '1';
748
        TX_FSM_State         <= WR_CLOCK_STATE;
749
      end if;
750
 
751
    end if;
752
  end process;
753
 
754 202 jshamlet
  U_TX_CRC : entity work.sdlc_crc16_ccitt
755
  generic map(
756
    Poly_Init                => Poly_Init,
757
    Reset_Level              => Reset_Level
758
  )
759
  port map(
760
    Clock                    => Clock,
761
    Reset                    => Reset,
762 192 jshamlet
    --
763 202 jshamlet
    Clear                    => TX_CRC_Clr,
764
    Wr_En                    => TX_CRC_En,
765
    Wr_Data                  => TX_Wr_Data,
766 192 jshamlet
    --
767 202 jshamlet
    CRC16_Valid              => TX_CRC_Valid,
768
    CRC16_Out                => TX_CRC_Data
769 192 jshamlet
  );
770
 
771 278 jshamlet
  TX_Serial_proc: process( Clock, Reset )
772
  begin
773
    if( Reset = Reset_Level )then
774
      TX_State               <= IDLE;
775
      SDLC_Out               <= '1';
776
      TX_Arm                 <= '0';
777
      TX_Buffer              <= (others => '0');
778
      TX_Flag                <= '0';
779
      TX_ShftReg             <= (others => '0');
780
      TX_BitStuff            <= (others => '0');
781
      TX_BitCntr             <= (others => '1');
782
      TX_Req_Next               <= '0';
783
    elsif( rising_edge(Clock) )then
784 192 jshamlet
 
785 278 jshamlet
      if( TX_Wr_En = '1' and TX_Arm = '0')then
786
        TX_Arm               <= '1';
787
        TX_Buffer_Flag       <= TX_Wr_Flag;
788
        TX_Buffer_Data       <= TX_Wr_Data;
789
      end if;
790
 
791
      TX_Req_Next               <= '0';
792
 
793
      case( TX_State )is
794
        when INIT =>
795
          SDLC_Out           <= '1';
796
          TX_State           <= IDLE;
797
 
798
        when IDLE =>
799
          SDLC_Out           <= '1';
800
          if( TX_Arm = '1' and BClk_FE = '1' )then
801
            TX_Arm           <= '0';
802
            TX_BitCntr       <= (others => '0');
803
            TX_BitStuff      <= (others => '0');
804
            TX_Flag          <= TX_Buffer_Flag;
805
            TX_ShftReg       <= TX_Buffer_Data;
806
            TX_Req_Next      <= '1';
807
            TX_State         <= XMIT;
808
          end if;
809
 
810
        when XMIT =>
811
          SDLC_Out           <= TX_ShftReg(conv_integer(TX_BitSel));
812
          TX_BitCntr         <= TX_BitCntr + BClk_FE;
813
          if( BClk_RE = '1' )then
814
            TX_BitStuff      <= TX_BitStuff(3 downto 0) &
815
                                TX_ShftReg(conv_integer(TX_BitSel));
816
          end if;
817
          if( BClk_FE = '1' )then
818
            if( TX_BitCntr >= 7 )then
819
              TX_State       <= TERM;
820
            elsif( and_reduce(TX_BitStuff) = '1' and TX_Flag = '0' )then
821
              TX_BitStuff    <= (others => '0');
822
              TX_State       <= SPACE;
823
            else
824
              TX_BitCntr     <= TX_BitCntr + 1;
825
            end if;
826
          end if;
827
 
828
        when SPACE =>
829
          SDLC_Out           <= '0';
830
          if( BClk_FE = '1' )then
831
            TX_State         <= XMIT;
832
          end if;
833
 
834
        when TERM =>
835
          if( TX_Arm = '1' )then
836
            TX_State         <= LD_NEXT;
837
          else
838
            TX_State         <= IDLE;
839
          end if;
840
 
841
        when LD_NEXT =>
842
          TX_Arm             <= '0';
843
          TX_BitCntr         <= (others => '0');
844
          TX_Flag            <= TX_Buffer_Flag;
845
          TX_ShftReg         <= TX_Buffer_Data;
846
          TX_Req_Next        <= '1';
847
          TX_State           <= XMIT;
848
          if( and_reduce(TX_BitStuff) = '1' and TX_Flag = '0' )then
849
            TX_BitStuff      <= (others => '0');
850
            TX_State         <= SPACE;
851
          end if;
852
 
853
        when others => null;
854
      end case;
855
 
856
      if( BClk_Okay = '0' )then
857
        TX_State                <= INIT;
858
      end if;
859
 
860
    end if;
861
  end process;
862
 
863 202 jshamlet
-- ***************************************************************************
864
-- *                     Serial Receive Path                                 *
865
-- ***************************************************************************
866 192 jshamlet
 
867 278 jshamlet
IF_Is_Master: if( Set_As_Master )generate
868 192 jshamlet
 
869 278 jshamlet
  Input_proc: process( Clock, Reset )
870
  begin
871
    if( Reset = Reset_Level )then
872
      RX_LatchEn_SR          <= (others => '0');
873
      RX_Serial_SR           <= (others => '0');
874
    elsif( rising_edge(Clock) )then
875
      RX_LatchEn_SR          <= RX_LatchEn_SR(Clock_Offset - 1 downto 0) & BClk_RE;
876
      RX_Serial_SR           <= RX_Serial_SR(0) & SDLC_In;
877
    end if;
878
  end process;
879 202 jshamlet
 
880 278 jshamlet
  RX_LatchEn                 <= RX_LatchEn_M;
881
 
882
end generate;
883
 
884
IF_Is_Slave: if( not Set_As_Master )generate
885
 
886
  Input_proc: process( Clock, Reset )
887
  begin
888
    if( Reset = Reset_Level )then
889
      RX_Serial_SR           <= (others => '0');
890
    elsif( rising_edge(Clock) )then
891
      RX_Serial_SR           <= RX_Serial_SR(0) & SDLC_In;
892
    end if;
893
  end process;
894
 
895
  RX_LatchEn                 <= RX_LatchEn_S;
896
 
897
end generate;
898
 
899
  RX_Serial_proc: process( Clock, Reset )
900
  begin
901
    if( Reset = Reset_Level )then
902
 
903
      RX_BitStuff_SR         <= (others => '0');
904
      RX_Flag_SR             <= (others => '0');
905
      RX_Idle_Cntr           <= (others => '0');
906
 
907
      RX_State               <= IDLE;
908
      RX_Idle                <= '0';
909
 
910
      RX_Buffer              <= (others => '0');
911
      RX_BitCntr             <= (others => '0');
912
 
913
      RX_Valid               <= '0';
914
      RX_Flag                <= '0';
915
      RX_Data                <= (others => '0');
916
 
917
    elsif( rising_edge(Clock) )then
918
 
919
      if( RX_LatchEn = '1' )then
920
        RX_Flag_SR           <= RX_Flag_SR(6 downto 0) & RX_Serial;
921
        if( RX_State = IDLE )then
922
          RX_Flag_SR         <= (others => '0');
923
        end if;
924
 
925
        RX_Idle_Cntr         <= RX_Idle_Cntr + RX_Serial;
926
        if( and_reduce(RX_Idle_Cntr) = '1' )then
927
          RX_Idle_Cntr       <= "111";
928
        end if;
929
      end if;
930
 
931
      if( RX_Serial = '0' )then
932
        RX_Idle_Cntr         <= (others => '0');
933
      end if;
934
 
935
      RX_Valid               <= '0';
936
      RX_Flag                <= '0';
937
      RX_Idle                <= '0';
938
 
939
      case( RX_State )is
940
 
941
        when INIT =>
942
          RX_Idle            <= '1';
943
          RX_State           <= IDLE;
944
 
945
        when IDLE =>
946
          RX_Idle            <= '1';
947
          RX_BitCntr         <= (others => '0');
948
          RX_BitStuff_SR     <= (others => '0');
949
          if( RX_Serial = '0' )then
950
            RX_State         <= RCV_DATA;
951
          end if;
952
 
953
        when RCV_DATA =>
954
          if( RX_Term = '1' )then
955
            RX_State         <= WRITE_DATA;
956
          end if;
957
          if( RX_LatchEn = '1' )then
958
            RX_Buffer(conv_integer(RX_BitSel)) <= RX_Serial;
959
            RX_BitStuff_SR   <= RX_BitStuff_SR(3 downto 0) & RX_Serial;
960
            RX_BitCntr       <= RX_BitCntr + 1;
961
 
962
            if( and_reduce(RX_BitStuff_SR) = '1' )then
963
              RX_BitStuff_SR <= (others => '0');
964
              if( RX_Serial = '0' )then
965
                RX_BitCntr   <= RX_BitCntr;
966
                RX_State     <= SKIP_ZERO;
967
              end if;
968
            end if;
969
          end if;
970
 
971
        when SKIP_ZERO =>
972
          RX_State           <= RCV_DATA;
973
 
974
        when WRITE_DATA =>
975
          RX_BitCntr         <= (others => '0');
976
          RX_Valid           <= '1';
977
          RX_Data            <= RX_Buffer;
978
          if( RX_Flag_SR = SDLC_Flag )then
979
            RX_Flag          <= '1';
980
          end if;
981
          RX_State           <= RCV_DATA;
982
 
983
        when others => null;
984
      end case;
985
 
986
      -- If we just shifted in the flag character, and the bit counter isn't
987
      --  0x0, then our bit counter is out of alignment. Reset it to zero so
988
      --  that the next word is clocked in correctly.
989
      if( RX_Flag_SR = SDLC_Flag and RX_BitCntr > 0 )then
990
         RX_BitCntr          <= (others => '0');
991
      end if;
992
 
993
      -- If the serial line goes idle (In the marking state for more than 7
994
      --  bit times), and the FSM isn't already in IDLE, force it to IDLE.
995
      if( and_reduce(RX_Idle_Cntr) = '1' and RX_State /= IDLE )then
996
        RX_State             <= IDLE;
997
      end if;
998
 
999
      -- If the bit clock is no longer valid, soft-reset to the INIT state.
1000
      if( BClk_Okay = '0' )then
1001
        RX_State             <= INIT;
1002
      end if;
1003
 
1004
    end if;
1005
  end process;
1006
 
1007
  Packet_Marker_proc: process( Clock, Reset )
1008
  begin
1009
    if( Reset = Reset_Level )then
1010
      Pkt_State              <= IDLE;
1011
      First_Byte             <= '0';
1012
      RX_Frame_Start         <= '0';
1013
      RX_Frame_Stop          <= '0';
1014
      RX_Frame_Valid         <= '0';
1015
      RX_Frame_Data          <= x"00";
1016
    elsif( rising_edge(Clock) )then
1017
      RX_Frame_Start         <= '0';
1018
      RX_Frame_Stop          <= '0';
1019
      RX_Frame_Valid         <= '0';
1020
 
1021
      case( Pkt_State )is
1022
        when IDLE =>
1023
          if( RX_Valid = '1' and RX_Flag = '1' )then
1024
            Pkt_State        <= FRAME_START;
1025
          end if;
1026
 
1027
        when FRAME_START =>
1028
            if( RX_Valid = '1' and RX_Flag = '0' )then
1029
              RX_Frame_Start <= '1';
1030
              First_Byte     <= '1';
1031
              Pkt_State      <= FRAME_DATA;
1032
            end if;
1033
 
1034
        when FRAME_DATA =>
1035
          First_Byte         <= '0';
1036
          if( (RX_Valid = '1' and RX_Flag = '0') or
1037
            First_Byte = '1' )then
1038
            RX_Frame_Valid   <= '1';
1039
            RX_Frame_Data    <= RX_Data;
1040
          elsif( RX_Valid = '1' and RX_Flag = '1' )then
1041
            Pkt_State        <= FRAME_STOP;
1042
          end if;
1043
 
1044
        when FRAME_STOP =>
1045
          RX_Frame_Stop      <= not RX_Idle;
1046
          Pkt_State          <= IDLE;
1047
 
1048
        when others => null;
1049
      end case;
1050
 
1051
      if( RX_Idle = '1' and Pkt_State /= IDLE )then
1052
        Pkt_State            <= FRAME_STOP;
1053
      end if;
1054
 
1055
    end if;
1056
  end process;
1057
 
1058 192 jshamlet
  U_RX_CRC : entity work.sdlc_crc16_ccitt
1059
  generic map(
1060
    Poly_Init                => Poly_Init,
1061
    Reset_Level              => Reset_Level
1062
  )
1063
  port map(
1064
    Clock                    => Clock,
1065
    Reset                    => Reset,
1066
    --
1067 202 jshamlet
    Clear                    => RX_Frame_Start,
1068
    Wr_En                    => RX_Frame_Valid,
1069
    Wr_Data                  => RX_Frame_Data,
1070 192 jshamlet
    --
1071 202 jshamlet
    CRC16_Valid              => RX_CRC_Valid,
1072
    CRC16_Out                => RX_CRC_Data
1073 192 jshamlet
  );
1074
 
1075 278 jshamlet
  CRC_History_proc: process( Clock, Reset )
1076
  begin
1077
    if( Reset = Reset_Level )then
1078
      RX_CRC_Hist(0)         <= x"0000";
1079
      RX_CRC_Hist(1)         <= x"0000";
1080
      RX_CRC_Hist(2)         <= x"0000";
1081
    elsif( rising_edge(Clock) )then
1082
      if( RX_CRC_Valid = '1' )then
1083
        RX_CRC_Hist(2)       <= RX_CRC_Hist(1);
1084
        RX_CRC_Hist(1)       <= RX_CRC_Hist(0);
1085
        RX_CRC_Hist(0)       <= RX_CRC_Data;
1086
      end if;
1087
    end if;
1088
  end process;
1089 202 jshamlet
 
1090 278 jshamlet
  RX_Packet_RAM_proc: process( Reset, Clock )
1091
  begin
1092
    if( Reset = Reset_Level )then
1093
      RX_FSM_State           <= WAIT_FOR_CLOCK;
1094
 
1095
      DP_Port1_Addr          <= x"00";
1096
      DP_Port1_RWn           <= '1';
1097
      DP_Port1_WrData        <= x"00";
1098
      DP_Port1_Req           <= '0';
1099
 
1100
      RX_Length              <= x"00";
1101
 
1102
      RX_CRC_Rcvd            <= x"0000";
1103
 
1104
      RX_Interrupt           <= '0';
1105
 
1106
    elsif( rising_edge(Clock) )then
1107
 
1108
      DP_Port1_Addr          <= x"00";
1109
      DP_Port1_RWn           <= '1';
1110
      DP_Port1_WrData        <= x"00";
1111
      DP_Port1_Req           <= '0';
1112
 
1113
      RX_Interrupt           <= '0';
1114
 
1115
      case( RX_FSM_State )is
1116
 
1117
        when WAIT_FOR_CLOCK =>
1118
          RX_FSM_State       <= WAIT_FOR_FLAG;
1119
 
1120
        when WAIT_FOR_FLAG =>
1121
          if( RX_Frame_Start = '1' )then
1122
            RX_Length        <= x"00";
1123
            RX_FSM_State     <= RX_MESG_DATA;
1124
          end if;
1125
 
1126
        when RX_MESG_DATA =>
1127
          if( RX_Frame_Stop = '1' )then
1128
            RX_Length        <= RX_Length - 1;
1129
            RX_FSM_State         <= RX_CRC_UB_RD;
1130
          elsif( RX_Frame_Valid = '1' )then
1131
            RX_FSM_State     <= RX_WR_DATA;
1132
            if( RX_Length > 254 )then
1133
              RX_Length      <= ERR_LENGTH;
1134
              RX_FSM_State   <= RX_WR_COUNT;
1135
            end if;
1136
          end if;
1137
 
1138
        when RX_WR_DATA  =>
1139
          RX_Length          <= RX_Length + DP_Port1_Ack;
1140
          DP_Port1_Addr      <= RX_Length;
1141
          DP_Port1_WrData    <= RX_Frame_Data;
1142
          DP_Port1_RWn       <= '0';
1143
          DP_Port1_Req       <= '1';
1144
          if( DP_Port1_Ack = '1' )then
1145
            DP_Port1_Req     <= '0';
1146
            RX_FSM_State     <= RX_MESG_DATA;
1147
          end if;
1148
 
1149
        when RX_CRC_UB_RD =>
1150
          RX_Length          <= RX_Length - DP_Port1_Ack;
1151
          DP_Port1_Addr      <= RX_Length;
1152
          DP_Port1_Req       <= '1';
1153
          if( DP_Port1_Ack = '1' )then
1154
            DP_Port1_Req     <= '0';
1155
            RX_CRC_Rcvd_UB   <= DP_Port1_RdData;
1156
            RX_FSM_State     <= RX_CRC_LB_RD;
1157
          end if;
1158
 
1159
        when RX_CRC_LB_RD =>
1160
          DP_Port1_Addr      <= RX_Length;
1161
          DP_Port1_Req       <= '1';
1162
          if( DP_Port1_Ack = '1' )then
1163
            DP_Port1_Req     <= '0';
1164
            RX_CRC_Rcvd_LB   <= DP_Port1_RdData;
1165
            RX_FSM_State     <= RX_WR_CRC;
1166
          end if;
1167
 
1168
        when RX_WR_CRC =>
1169
          DP_Port1_Addr      <= CS_REGISTER;
1170
          DP_Port1_WrData    <= x"FF";
1171
          if( RX_CRC_Rcvd /= RX_CRC_Calc )then
1172
            DP_Port1_WrData  <= x"00";
1173
          end if;
1174
          DP_Port1_RWn       <= '0';
1175
          DP_Port1_Req       <= '1';
1176
          if( DP_Port1_Ack = '1' )then
1177
            DP_Port1_Req     <= '0';
1178
            RX_FSM_State     <= RX_WR_COUNT;
1179
          end if;
1180
 
1181
        when RX_WR_COUNT =>
1182
          DP_Port1_Addr      <= RX_REGISTER;
1183
          DP_Port1_WrData    <= RX_Length;
1184
          DP_Port1_RWn       <= '0';
1185
          DP_Port1_Req       <= '1';
1186
          if( DP_Port1_Ack = '1' )then
1187
            DP_Port1_Req     <= '0';
1188
            RX_Interrupt     <= '1';
1189
            RX_FSM_State     <= WAIT_FOR_FLAG;
1190
          end if;
1191
 
1192
        when others => null;
1193
      end case;
1194
 
1195
      if( BClk_Okay = '0' )then
1196
        RX_FSM_State         <= WAIT_FOR_FLAG;
1197
      end if;
1198
 
1199
    end if;
1200
  end process;
1201
 
1202 192 jshamlet
end architecture;

powered by: WebSVN 2.1.0

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