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 203

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
--                Checksum insertion and integrity checking.
27
--
28
-- Transmit Memory Map
29
-- "0_0000_0000" (0x000) TX Buffer START
30
-- "0_1111_1101" (0x0FD) TX Buffer END
31
-- "0_1111_1110" (0x0FE) Clock Status*
32
-- "0_1111_1111" (0x0FF) TX Length / Status**
33
--
34
-- Receive Memory Map
35
-- "1_0000_0000" (0x100) RX Buffer START
36 196 jshamlet
-- "1_1111_1101" (0x1FD) RX Buffer END
37 201 jshamlet
-- "1_1111_1110" (0x0FE) RX Checksum Status***
38
-- "1_1111_1111" (0x1FF) RX Length   Status****
39 192 jshamlet
--
40 201 jshamlet
-- *    Address 0xFE reports the SDLC bit clock status and updates on changes.
41
--      1) If BClk_Okay = '0' (Bitclock is NOT present), the field will report
42
--          0x00. Otherwise, it will report 0xFF if the bitclock is present.
43
--      2) Writing any value to the register will cause the controller to
44
--         silently reset the clock status without causing an interrupt.
45 199 jshamlet
--
46 201 jshamlet
-- **   This location serves as the control/status register for transmit
47
--      1) Writing a value between 1 and 253 will trigger the transmit engine,
48
--          using the write value as the packet length.
49
--      2) Values 0x00, 0xFE, or 0xFF are invalid, and will be ignored.
50
--      3) This value will change from the user written value to 0xFF once the
51
--          packet is transmitted to indicate the transmission is complete.
52 199 jshamlet
--
53 201 jshamlet
-- ***  This location serves as the status register for receive checksum test
54
--      1) A value of 0x00 indicates the CRC did NOT match, while a value
55
--         of 0xFF indicates that the recieved CRC matches the calculated CRC.
56
--
57
-- **** This location serves as the status register for the receive
58
--      1) This value is only updated on reception of a full frame, indicated
59
--          by a start followed by a stop flag. Incomplete frames are ignored.
60
--      2) If the packet CRC matches the transmitted CRC, the packet is
61
--          considered valid, and the received length (less CRC) is written.
62
--      3) If the packet CRC doesn't match, a value of ERR_CHECKSUM is written.
63
--      4) If too many bytes are received (buffer overflow), a value of
64
--          ERR_LENGTH is written.
65 192 jshamlet
 
66
library ieee;
67
  use ieee.std_logic_1164.all;
68
  use ieee.std_logic_unsigned.all;
69
  use ieee.std_logic_arith.all;
70
 
71
library work;
72
  use work.open8_pkg.all;
73
 
74
library work;
75
  use work.sdlc_serial_pkg.all;
76
 
77
entity o8_sdlc_if is
78
generic(
79 202 jshamlet
  Monitor_Enable             : boolean := false;
80 199 jshamlet
  Attach_Monitor_to_CPU_Side : boolean := false;
81 192 jshamlet
  Poly_Init                  : std_logic_vector(15 downto 0) := x"0000";
82
  Set_As_Master              : boolean := true;
83
  Clock_Offset               : integer := 6;
84
  BitClock_Freq              : real := 500000.0;
85
  Sys_Freq                   : real := 100000000.0;
86
  Reset_Level                : std_logic := '1';
87
  Address                    : ADDRESS_TYPE
88
);
89
port(
90
  Clock                      : in  std_logic;
91
  Reset                      : in  std_logic;
92
  --
93
  Bus_Address                : in  ADDRESS_TYPE;
94
  Wr_Enable                  : in  std_logic;
95
  Wr_Data                    : in  DATA_TYPE;
96
  Rd_Enable                  : in  std_logic;
97
  Rd_Data                    : out DATA_TYPE;
98
  Interrupt                  : out std_logic;
99
  -- Serial IO
100
  SDLC_In                    : in  std_logic;
101
  SDLC_SClk                  : in  std_logic;
102
  SDLC_MClk                  : out std_logic;
103
  SDLC_Out                   : out std_logic
104
);
105
end entity;
106
 
107
architecture behave of o8_sdlc_if is
108
 
109
  -- Connect the CPU to the dual-port memory
110
  constant Base_Addr         : std_logic_vector(15 downto 9)
111
                               := Address(15 downto 9);
112
 
113
  alias RAM_Upper_Addr       is Bus_Address(15 downto 9);
114
  alias RAM_Lower_Addr       is Bus_Address(8 downto 0);
115
 
116
  signal RAM_Addr_Match      : std_logic := '0';
117
  signal RAM_Wr_En           : std_logic := '0';
118
  signal RAM_Rd_En           : std_logic := '0';
119
  signal Rd_Data_i           : DATA_TYPE := OPEN8_NULLBUS;
120
 
121 196 jshamlet
  constant Reg_Sub_Addr      : std_logic_vector(8 downto 1) := x"7F";
122 192 jshamlet
 
123 196 jshamlet
  alias Reg_Upper_Addr       is Bus_Address(8 downto 1);
124
  alias Reg_Lower_Addr       is Bus_Address(0);
125
 
126
  signal Reg_Addr            : std_logic_vector(8 downto 1) := (others => '0');
127
  signal Reg_Sel             : std_logic := '0';
128 192 jshamlet
  signal Reg_Wr_En           : std_logic := '0';
129 196 jshamlet
  signal Reg_Clk_Sel         : std_logic := '0';
130
  signal Reg_TxS_Sel         : std_logic := '0';
131
 
132 192 jshamlet
  signal DP_Addr             : std_logic_vector(8 downto 0) := (others => '0');
133
  signal DP_Wr_Data          : DATA_IN_TYPE := x"00";
134
  signal DP_Wr_En            : std_logic := '0';
135
  signal DP_Rd_Data          : DATA_IN_TYPE := x"00";
136
 
137 202 jshamlet
  signal DP_Port0_Addr       : DATA_IN_TYPE  := x"00";
138
  signal DP_Port0_RWn        : std_logic     := '0';
139
  signal DP_Port0_WrData     : DATA_IN_TYPE  := x"00";
140
  signal DP_Port0_RdData     : DATA_IN_TYPE  := x"00";
141
  signal DP_Port0_Req        : std_logic     := '0';
142
  signal DP_Port0_Ack        : std_logic     := '0';
143
 
144
  signal DP_Port1_Addr       : DATA_IN_TYPE  := x"00";
145
  signal DP_Port1_RWn        : std_logic     := '0';
146
  signal DP_Port1_WrData     : DATA_IN_TYPE  := x"00";
147
  signal DP_Port1_RdData     : DATA_IN_TYPE  := x"00";
148
  signal DP_Port1_Req        : std_logic     := '0';
149
  signal DP_Port1_Ack        : std_logic     := '0';
150
 
151 192 jshamlet
  signal BClk_RE             : std_logic := '0';
152
  signal BClk_FE             : std_logic := '0';
153 202 jshamlet
  signal BClk_Okay           : std_logic     := '0';
154 192 jshamlet
 
155 202 jshamlet
  signal TX_Wr_En            : std_logic     := '0';
156
  signal TX_Wr_Flag          : std_logic     := '0';
157
  signal TX_Wr_Data          : DATA_IN_TYPE  := x"00";
158
  signal TX_Req_Next         : std_logic     := '0';
159 192 jshamlet
 
160 202 jshamlet
  signal TX_CRC_Clr          : std_logic     := '0';
161
  signal TX_CRC_En           : std_logic     := '0';
162
  signal TX_CRC_Data         : CRC_OUT_TYPE  := x"0000";
163
  signal TX_CRC_Valid        : std_logic     := '0';
164 192 jshamlet
 
165 202 jshamlet
  signal TX_Interrupt        : std_logic     := '0';
166 192 jshamlet
 
167 202 jshamlet
  signal RX_Valid            : std_logic     := '0';
168
  signal RX_Flag             : std_logic     := '0';
169
  signal RX_Data             : DATA_IN_TYPE;
170
  signal RX_Idle             : std_logic     := '0';
171 192 jshamlet
 
172 202 jshamlet
  signal RX_Frame_Start      : std_logic     := '0';
173
  signal RX_Frame_Stop       : std_logic     := '0';
174
  signal RX_Frame_Valid      : std_logic     := '0';
175
  signal RX_Frame_Data       : DATA_IN_TYPE  := x"00";
176 192 jshamlet
 
177 202 jshamlet
  signal RX_CRC_Valid        : std_logic     := '0';
178
  signal RX_CRC_Data         : CRC_OUT_TYPE  := x"0000";
179
 
180
  signal RX_Interrupt        : std_logic     := '0';
181
 
182 192 jshamlet
begin
183
 
184 202 jshamlet
-- ***************************************************************************
185
-- *          Open8 Bus Interface and Control Register Detection             *
186
-- ***************************************************************************
187
 
188 192 jshamlet
  -- This decode needs to happen immediately, to give the RAM a chance to
189
  --  do the lookup before we have to set Rd_Data
190
  RAM_Addr_Match             <= '1' when Base_Addr = RAM_Upper_Addr else '0';
191
  RAM_Wr_En                  <= RAM_Addr_Match and Wr_Enable;
192
 
193
  CPU_RAM_proc: process( Reset, Clock )
194
  begin
195
    if( Reset = Reset_Level )then
196
      Reg_Addr               <= (others => '0');
197
      Reg_Wr_En              <= '0';
198 196 jshamlet
      Reg_Clk_Sel            <= '0';
199
      Reg_TxS_Sel            <= '0';
200 192 jshamlet
      RAM_Rd_En              <= '0';
201
      Rd_Data                <= OPEN8_NULLBUS;
202
    elsif( rising_edge(Clock) )then
203 196 jshamlet
      Reg_Addr               <= Reg_Upper_Addr;
204
      Reg_Sel                <= Reg_Lower_Addr;
205 192 jshamlet
      Reg_Wr_En              <= RAM_Addr_Match and Wr_Enable;
206
 
207 196 jshamlet
      Reg_Clk_Sel            <= '0';
208
      Reg_TxS_Sel            <= '0';
209 192 jshamlet
      if( Reg_Addr = Reg_Sub_Addr )then
210 196 jshamlet
        Reg_Clk_Sel          <= Reg_Wr_En and not Reg_Sel;
211
        Reg_TxS_Sel          <= Reg_Wr_En and Reg_Sel;
212 192 jshamlet
      end if;
213
 
214
      RAM_Rd_En              <= RAM_Addr_Match and Rd_Enable;
215
      Rd_Data                <= OPEN8_NULLBUS;
216
      if( RAM_Rd_En = '1' )then
217
        Rd_Data              <= Rd_Data_i;
218
      end if;
219
    end if;
220
  end process;
221
 
222 202 jshamlet
-- ***************************************************************************
223
-- *                     Shared Dual-Port Memory                             *
224
-- ***************************************************************************
225
 
226 200 jshamlet
  U_RAM : entity work.sdlc_dp512b_ram
227 192 jshamlet
  port map(
228
    clock                    => Clock,
229
    address_a                => RAM_Lower_Addr,
230
    address_b                => DP_Addr,
231
    data_a                   => Wr_Data,
232
    data_b                   => DP_Wr_Data,
233
    wren_a                   => RAM_Wr_En,
234
    wren_b                   => DP_Wr_En,
235
    q_a                      => Rd_Data_i,
236
    q_b                      => DP_Rd_Data
237
  );
238
 
239 199 jshamlet
Attach_to_CPU_side: if( Monitor_Enable and Attach_Monitor_to_CPU_Side )generate
240
 
241
  U_MON: entity work.sdlc_monitor
242
  port map(
243
    clock                    => Clock,
244
    address                  => RAM_Lower_Addr,
245
    data                     => Wr_Data,
246
    wren                     => RAM_Wr_En,
247
    q                        => open
248
  );
249
end generate;
250
 
251
Attach_to_Int_side: if( Monitor_Enable and not Attach_Monitor_to_CPU_Side )generate
252
 
253
  U_MON: entity work.sdlc_monitor
254
  port map(
255
    clock                    => Clock,
256
    address                  => DP_Addr,
257
    data                     => DP_Wr_Data,
258
    wren                     => DP_Wr_En,
259
    q                        => open
260
  );
261
 
262
end generate;
263
 
264 202 jshamlet
-- ***************************************************************************
265
-- *                     Memory Arbitration                                  *
266
-- ***************************************************************************
267
 
268
  U_ARB : entity work.sdlc_serial_arbfsm
269
  generic map(
270
    Reset_Level              => Reset_Level
271
  )
272
  port map(
273
    Clock                    => Clock,
274
    Reset                    => Reset,
275
    --
276
    DP_Port0_Addr            => DP_Port0_Addr,
277
    DP_Port0_RWn             => DP_Port0_RWn,
278
    DP_Port0_WrData          => DP_Port0_WrData,
279
    DP_Port0_RdData          => DP_Port0_RdData,
280
    DP_Port0_Req             => DP_Port0_Req,
281
    DP_Port0_Ack             => DP_Port0_Ack,
282
    --
283
    DP_Port1_Addr            => DP_Port1_Addr,
284
    DP_Port1_RWn             => DP_Port1_RWn,
285
    DP_Port1_WrData          => DP_Port1_WrData,
286
    DP_Port1_RdData          => DP_Port1_RdData,
287
    DP_Port1_Req             => DP_Port1_Req,
288
    DP_Port1_Ack             => DP_Port1_Ack,
289
    --
290
    DP_Addr                  => DP_Addr,
291
    DP_Wr_Data               => DP_Wr_Data,
292
    DP_Wr_En                 => DP_Wr_En,
293
    DP_Rd_Data               => DP_Rd_Data
294
  );
295
 
296
-- ***************************************************************************
297
-- *                        Serial BitClock                                  *
298
-- ***************************************************************************
299
 
300 192 jshamlet
  U_BCLK : entity work.sdlc_serial_clk
301
  generic map(
302
    Set_As_Master            => Set_As_Master,
303
    BitClock_Freq            => BitClock_Freq,
304
    Reset_Level              => Reset_Level,
305
    Sys_Freq                 => Sys_Freq
306
  )
307
  port map(
308
    Clock                    => Clock,
309
    Reset                    => Reset,
310
    --
311
    BClk_In                  => SDLC_SClk,
312
    BClk_Out                 => SDLC_MClk,
313
    BClk_FE                  => BClk_FE,
314
    BClk_RE                  => BClk_RE,
315
    BClk_Okay                => BClk_Okay
316
  );
317
 
318 202 jshamlet
-- ***************************************************************************
319
-- *                     Serial Transmit Path                                *
320
-- ***************************************************************************
321
 
322
  U_TXFSM: entity work.sdlc_serial_txfsm
323 192 jshamlet
  generic map(
324
    Reset_Level              => Reset_Level
325
  )
326
  port map(
327
    Clock                    => Clock,
328
    Reset                    => Reset,
329
    --
330
    BClk_Okay                => BClk_Okay,
331
    --
332 196 jshamlet
    Reg_Clk_Sel              => Reg_Clk_Sel,
333
    Reg_TxS_Sel              => Reg_TxS_Sel,
334 192 jshamlet
    --
335 202 jshamlet
    DP_Port0_Addr            => DP_Port0_Addr,
336
    DP_Port0_RWn             => DP_Port0_RWn,
337
    DP_Port0_WrData          => DP_Port0_WrData,
338
    DP_Port0_RdData          => DP_Port0_RdData,
339
    DP_Port0_Req             => DP_Port0_Req,
340
    DP_Port0_Ack             => DP_Port0_Ack,
341 192 jshamlet
    --
342
    TX_Wr_En                 => TX_Wr_En,
343
    TX_Wr_Flag               => TX_Wr_Flag,
344
    TX_Wr_Data               => TX_Wr_Data,
345
    TX_Req_Next              => TX_Req_Next,
346
    --
347
    TX_CRC_Clr               => TX_CRC_Clr,
348
    TX_CRC_En                => TX_CRC_En,
349
    TX_CRC_Data              => TX_CRC_Data,
350
    TX_CRC_Valid             => TX_CRC_Valid,
351
    --
352 202 jshamlet
    TX_Interrupt             => TX_Interrupt
353
  );
354
 
355
  U_TX_CRC : entity work.sdlc_crc16_ccitt
356
  generic map(
357
    Poly_Init                => Poly_Init,
358
    Reset_Level              => Reset_Level
359
  )
360
  port map(
361
    Clock                    => Clock,
362
    Reset                    => Reset,
363 192 jshamlet
    --
364 202 jshamlet
    Clear                    => TX_CRC_Clr,
365
    Wr_En                    => TX_CRC_En,
366
    Wr_Data                  => TX_Wr_Data,
367 192 jshamlet
    --
368 202 jshamlet
    CRC16_Valid              => TX_CRC_Valid,
369
    CRC16_Out                => TX_CRC_Data
370 192 jshamlet
  );
371
 
372
  U_TX_SER : entity work.sdlc_serial_tx
373
  generic map(
374
    Reset_Level              => Reset_Level
375
  )
376
  port map(
377
    Clock                    => Clock,
378
    Reset                    => Reset,
379
    --
380
    BClk_FE                  => BClk_FE,
381
    BClk_RE                  => BClk_RE,
382
    BClk_Okay                => BClk_Okay,
383
    --
384
    TX_En                    => TX_Wr_En,
385
    TX_FSS_Flag              => TX_Wr_Flag,
386
    TX_Data                  => TX_Wr_Data,
387
    TX_Req_Next              => TX_Req_Next,
388
    --
389
    Serial_Out               => SDLC_Out
390
  );
391
 
392 202 jshamlet
-- ***************************************************************************
393
-- *                     Serial Receive Path                                 *
394
-- ***************************************************************************
395 192 jshamlet
 
396
  U_RX_SER : entity work.sdlc_serial_rx
397
  generic map(
398
    Set_As_Master            => Set_As_Master,
399
    Clock_Offset             => Clock_Offset,
400
    Reset_Level              => Reset_Level
401
  )
402
  port map(
403
    Clock                    => Clock,
404
    Reset                    => Reset,
405
    --
406
    BClk_RE                  => BClk_RE,
407
    BClk_Okay                => BClk_Okay,
408
    --
409
    Serial_In                => SDLC_In,
410
    --
411
    RX_Valid                 => RX_Valid,
412
    RX_Flag                  => RX_Flag,
413
    RX_Data                  => RX_Data,
414
    RX_Idle                  => RX_Idle
415
  );
416
 
417 202 jshamlet
  U_RX_PKT : entity work.sdlc_serial_frame
418
  generic map(
419
    Reset_Level              => Reset_Level
420
  )
421
  port map(
422
    Clock                    => Clock,
423
    Reset                    => Reset,
424
    --
425
    RX_Valid                 => RX_Valid,
426
    RX_Flag                  => RX_Flag,
427
    RX_Data                  => RX_Data,
428
    RX_Idle                  => RX_Idle,
429
    --
430
    RX_Frame_Start           => RX_Frame_Start,
431
    RX_Frame_Stop            => RX_Frame_Stop,
432
    RX_Frame_Valid           => RX_Frame_Valid,
433
    RX_Frame_Data            => RX_Frame_Data
434
  );
435
 
436 192 jshamlet
  U_RX_CRC : entity work.sdlc_crc16_ccitt
437
  generic map(
438
    Poly_Init                => Poly_Init,
439
    Reset_Level              => Reset_Level
440
  )
441
  port map(
442
    Clock                    => Clock,
443
    Reset                    => Reset,
444
    --
445 202 jshamlet
    Clear                    => RX_Frame_Start,
446
    Wr_En                    => RX_Frame_Valid,
447
    Wr_Data                  => RX_Frame_Data,
448 192 jshamlet
    --
449 202 jshamlet
    CRC16_Valid              => RX_CRC_Valid,
450
    CRC16_Out                => RX_CRC_Data
451 192 jshamlet
  );
452
 
453 202 jshamlet
  U_RX_FSM : entity work.sdlc_serial_rxfsm
454
  generic map(
455
    Reset_Level              => Reset_Level
456
  )
457
  port map(
458
    Clock                    => Clock,
459
    Reset                    => Reset,
460
    --
461
    BClk_Okay                => BClk_Okay,
462
    --
463
    DP_Port1_Addr            => DP_Port1_Addr,
464
    DP_Port1_RWn             => DP_Port1_RWn,
465
    DP_Port1_WrData          => DP_Port1_WrData,
466
    DP_Port1_RdData          => DP_Port1_RdData,
467
    DP_Port1_Req             => DP_Port1_Req,
468
    DP_Port1_Ack             => DP_Port1_Ack,
469
    --
470
    RX_CRC_Valid             => RX_CRC_Valid,
471
    RX_CRC_Data              => RX_CRC_Data,
472
    --
473
    RX_Frame_Start           => RX_Frame_Start,
474
    RX_Frame_Stop            => RX_Frame_Stop,
475
    RX_Frame_Valid           => RX_Frame_Valid,
476
    RX_Frame_Data            => RX_Frame_Data,
477
    --
478
    RX_Interrupt             => RX_Interrupt
479
  );
480
 
481
-- ***************************************************************************
482
-- *                        Merge Interrupts                                 *
483
-- ***************************************************************************
484
 
485
   Interrupt_merge_proc: process( Clock, Reset )
486
   begin
487
     if( Reset = Reset_Level )then
488
       Interrupt             <= '0';
489
     elsif( rising_edge(Clock) )then
490
       Interrupt             <= RX_Interrupt or TX_Interrupt;
491
     end if;
492
   end process;
493
 
494 192 jshamlet
end architecture;

powered by: WebSVN 2.1.0

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