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

Subversion Repositories p9813_rgb_led_string_driver

[/] [p9813_rgb_led_string_driver/] [trunk/] [rtl/] [VHDL/] [async_syscon_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
--------------------------------------------------------------------------
2
-- Package of async_syscon components
3
--
4
 
5
library IEEE;
6
use IEEE.STD_LOGIC_1164.ALL;
7
use IEEE.NUMERIC_STD.ALL;
8
 
9
package async_syscon_pack is
10
 
11
-- Component declarations not provided any more.
12
-- With VHDL '93 and newer, component declarations are allowed,
13
-- but not required.
14
--
15
-- If you please, try direct instantiation instead, for example:
16
--
17
--   instance_name : entity work.entity_name(beh)
18
--
19
 
20
end async_syscon_pack;
21
 
22
package body async_syscon_pack is
23
end async_syscon_pack;
24
 
25
---------------------------------------------------------------------------------------
26
--
27
-- Author: John Clayton
28
-- Date  : Dec. 27, 2013
29
-- Update: 12/27/13 copied async_syscon module, removed the serial interface.
30
--         02/05/14 Added line feed as a whitespace character, to 
31
--                  char_is_whitespace.
32
--         02/06/14 Made resp_cyc a direct function of the state machine state.
33
--                  This allows it to be asserted even when resp_ack_i is tied
34
--                  to '1' all the time...
35
--         02/13/14 Made a slight enhancement to the processing of comments.
36
--                  Previously, all comments were treated as "full line"
37
--                  comments, causing any valid commands preceding the
38
--                  comment to be ignored, since the entire line was being
39
--                  ignored.  I realized that a very small value
40
--                  check on cmd_ptr could differentiate between full line
41
--                  comments, and ones for which there might actually be
42
--                  a valid command.  The enhanced design can process the
43
--                  valid commands.
44
--         02/14/14 Happy Valentine's Day!  Fixed a "wacky" bug which caused
45
--                  an extra digit to be displayed for address and data fields.
46
--                  Added "0" command suffix, which prevents the bus address
47
--                  from incrementing during read, write and fill operations.
48
--                  It's useful for working with FIFOs that have read/write
49
--                  ports mapped to a single address, instead of a whole
50
--                  range of addresses.
51
--         02/27/14 Refined the CHECK_SUFFICES state by adding a jump to
52
--                  START_EXECUTION when ENTER_CHAR is found in the suffix
53
--                  position, thus preserving the "repeat last read with
54
--                  previous address and quantity" function.
55
--
56
-- Description
57
---------------------------------------------------------------------------------------
58
-- This is an 8-bit parallel ASCII character driven interface to a system
59
-- controller driving a "Wishbone" type of parallel system bus.
60
--
61
-- Specifically, the unit allows the user to send text commands to the 
62
-- "ascii_syscon" unit, in order to generate read and write cycles on the
63
-- Wishbone compatible bus.  The command structure is quite terse and spartan
64
-- in nature, this is for the sake of the logic itself.
65
--
66
-- The command line buffer is small enough to be implemented without the use
67
-- of dedicated BRAM memory blocks, and the menus and command responses were
68
-- kept as small as possible.  In most cases, the responses from the unit to
69
-- the user consist of a "newline" and one or two visible characters.  The
70
-- command structure consists of the following commands and responses:
71
--
72
-- Command Syntax              Purpose
73
-- ---------------             ---------------------------------------
74
-- w aaaa dddd dddd dddd...    Write data items "dddd" starting at address "aaaa"
75
--                             using sequential addresses.
76
--                             (If the data field is missing, nothing is done).
77
-- w0 aaaa dddd dddd dddd...   Write data items "dddd" at address "aaaa"
78
--                             without incrementing the address.
79
--                             (If the data field is missing, nothing is done).
80
-- f aaaa dddd xx              "Fill": Write data "dddd" starting at address "aaaa"
81
--                             perform this "xx" times at sequential addresses.
82
--                             (The quantity field is optional, default is 1).
83
-- f0 aaaa dddd xx             "Fill": Write data "dddd" starting at address "aaaa"
84
--                             perform this "xx" times at the same address.
85
--                             (The quantity field is optional, default is 1).
86
-- r aaaa xx                   Read data starting from address "aaaa."
87
--                             Perform this "xx" times at sequential addresses.
88
--                             (The quantity field is optional, default is 1).
89
-- r0 aaaa xx                  Read data from address "aaaa."
90
--                             Perform this "xx" times, using the same address.
91
--                             (The quantity field is optional, default is 1).
92
-- i                           Send a reset pulse to the system. (initialize).
93
--
94
-- <COMMENT_CHAR>              "Single Line" type Comment token.  Characters
95
--                             after the token are ignored until <ENTER>.
96
--                             This enables applications which send
97
--                             files to the unit to include comments for
98
--                             display and as an aid to understanding.
99
--                             The comment token is a constant, change it
100
--                             to be whatever makes sense!
101
--
102
-- Response from async_syscon  Meaning
103
-- --------------------------  ---------------------------------------
104
-- OK                          Command received and performed.  No errors.
105
-- ?                           Command buffer full, without receiving "enter."
106
-- C?                          Command not recognized.
107
-- A?                          Address field syntax error.
108
-- D?                          Data field syntax error.
109
-- Q?                          Quantity field syntax error.
110
-- !                           No "ack_i", or else "err_i" received from bus.
111
-- B!                          No "bg_i" received from master.
112
--
113
-- NOTES on the operation of this unit:
114
--
115
-- - The unit generates a command prompt which is "-> ".
116
-- - Capitalization is not important.
117
-- - Each command is terminated by the "enter" key (0x0d character).
118
--   Commands are executed as soon as "enter" is received.
119
-- - Trailing parameters need not be re-entered.  Their values will
120
--   remain the same as their previous settings.
121
-- - Use of the backspace key is supported, so mistakes can be corrected.
122
-- - The length of the command line is limited to a fixed number of
123
--   characters, as configured by parameter.
124
-- - Fields are separated by white space, including "tab" and/or "space"
125
-- - All numerical fields are interpreted as hexadecimal numbers.
126
--   Decimal is not supported.
127
-- - Numerical field values are retained between commands.  If a "r" is issued
128
--   without any fields following it, the previous values will be used.  A
129
--   set of "quantity" reads will take place at sequential addresses.
130
--   If a "f" is issued without any fields following it, the previous data
131
--   value will be written "quantity" times at sequential addresses, starting
132
--   from the next location beyond where the last command ended.
133
-- - If the user does not wish to use "ack" functionality, simply tie the
134
--   "ack_i" input to logic 1, and then the ! response will never be generated.
135
-- - The data which is read in by the "r" command is displayed using lines
136
--   which begin with the address, followed by the data fields.  The number
137
--   of data fields displayed per line (following the address) is adjustable
138
--   by setting a parameter.  No other display format adjustments can be made.
139
-- - There is currently only a single watchdog timer.  It begins to count at
140
--   the time the "enter" is received to execute a command.  If the bus is granted
141
--   and the ack is received before the expiration of the timer, then the
142
--   cycle will complete normally.  Therefore, the watchdog timeout value
143
--   needs to include time for the request and granting of the bus, in
144
--   addition to the time needed for the actual bus cycle to complete.
145
--
146
--
147
-- Currently, there is only a single indicator (stb_o) generated during bus
148
-- output cycles which are generated from this unit.
149
-- The user can easily implement decoding logic based upon adr_o and stb_o
150
-- which would serve as multiple "stb_o" type signals for different cores
151
-- which would be sharing the same bus.
152
--
153
-- The data bus supported by this module is separate input/output type of bus.
154
-- However, if a single tri-state dat_io bus is desired, it can be added
155
-- to the module without too much trouble.  Supposedly the only difference
156
-- between the two forms of data bus is that one of them avoids using tri-state
157
-- at the cost of doubling the number of interconnects used to carry data back
158
-- and forth...  Some people say that tri-state should be avoided for use
159
-- in internal busses in ASICs.  Maybe they are right.
160
-- But in FPGAs tri-state seems to work pretty well, even for internal busses.
161
--
162
-- Parameters are provided to configure the width of the different command
163
-- fields.  To simplify the logic for binary to hexadecimal conversion, these
164
-- parameters allow adjustment in units of 1 hex digit, not anything smaller.
165
-- If your bus has 10 bits, for instance, simply set the address width to 3
166
-- which produces 12 bits, and then just don't use the 2 msbs of address
167
-- output.
168
--
169
-- No support for the optional Wishbone "retry" (rty_i) input is provided at
170
-- this time.
171
-- No support for "tagn_o" bits is provided at this time, although a register
172
-- might be added external to this module in order to implement to tag bits.
173
-- No BLOCK or RMW cycles are supported currently, so cyc_o is equivalent to
174
-- stb_o...
175
-- The output busses are not tri-stated.  The user may add tri-state buffers
176
-- external to the module, using "stb_o" to enable the buffer outputs.
177
--
178
---------------------------------------------------------------------------------------
179
 
180
library IEEE;
181
use IEEE.STD_LOGIC_1164.ALL;
182
use IEEE.NUMERIC_STD.ALL;
183
 
184
entity ascii_syscon is
185
    generic (
186
      ADR_DIGITS      : natural :=   4; -- # of hex digits for address
187
      DAT_DIGITS      : natural :=   4; -- # of hex digits for data
188
      QTY_DIGITS      : natural :=   2; -- # of hex digits for quantity
189
      CMD_BUFFER_SIZE : natural :=  32; -- # of chars in the command buffer
190
      WATCHDOG_VALUE  : natural := 200; -- # of sys_clks before ack is expected
191
      DISPLAY_FIELDS  : natural :=   8  -- # of fields/line
192
    );
193
    port (
194
 
195
      sys_rst_n    : in  std_logic;
196
      sys_clk      : in  std_logic;
197
      sys_clk_en   : in  std_logic;
198
 
199
      -- Parallel ASCII I/O
200
      cmd_char_i   : in  unsigned(7 downto 0);
201
      cmd_we_i     : in  std_logic;
202
      cmd_ack_o    : out std_logic;
203
      cmd_echo_o   : out std_logic;
204
      resp_char_o  : out unsigned(7 downto 0);
205
      resp_cyc_o   : out std_logic;
206
      resp_ack_i   : in  std_logic;
207
      cmd_done_o   : out std_logic;
208
 
209
      -- Master Bus IO
210
      master_bg_i  : in  std_logic;
211
      master_ack_o : out std_logic;
212
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
213
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
214
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
215
      master_stb_i : in  std_logic;
216
      master_we_i  : in  std_logic;
217
      master_br_o  : out std_logic;
218
 
219
      -- System Bus IO
220
      ack_i        : in  std_logic;
221
      err_i        : in  std_logic;
222
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
223
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
224
      rst_o        : out std_logic;
225
      stb_o        : out std_logic;
226
      cyc_o        : out std_logic;
227
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
228
      we_o         : out std_logic
229
    );
230
end ascii_syscon;
231
 
232
library IEEE;
233
use IEEE.STD_LOGIC_1164.ALL;
234
use IEEE.NUMERIC_STD.ALL;
235
 
236
library work;
237
use work.function_pack.all;
238
use work.async_syscon_pack.all;
239
 
240
architecture beh of ascii_syscon is
241
 
242
-- Constants
243
constant CMD_PTR_BITS                 : natural := bit_width(CMD_BUFFER_SIZE);
244
constant DISPLAY_FIELD_COUNT_BITS     : natural := bit_width(DISPLAY_FIELDS);
245
constant DISPLAY_ADR_DIGIT_COUNT_BITS : natural := bit_width(ADR_DIGITS);
246
constant DISPLAY_DAT_DIGIT_COUNT_BITS : natural := bit_width(DAT_DIGITS);
247
constant WATCHDOG_TIMER_BITS          : natural := timer_width(WATCHDOG_VALUE);
248
 
249
constant BACKSPACE_CHAR      : unsigned := "00001000";
250
constant ENTER_CHAR          : unsigned := "00001101";
251
constant COMMENT_CHAR        : unsigned := "00100011"; -- '#' character
252
--constant COMMENT_CHAR        : unsigned := "00101101"; -- '-' character
253
 
254
-- Internal signal declarations
255
  -- For the state machine
256
type FSM_STATE_TYPE is (IDLE, SEND_WELCOME_STRING, SEND_OK, SEND_PROMPT,
257
                        CHECK_NEW_CHAR, SEND_CRLF, PARSE_ERR_INDICATOR_CRLF,
258
                        ERR_INDICATOR, BG_ERR_INDICATOR, SEND_QUESTION,
259
                        SCAN_CMD, CHECK_SUFFICES, SCAN_ADR_WHITESPACE,
260
                        GET_ADR_FIELD, SCAN_DAT_WHITESPACE, GET_DAT_FIELD,
261
                        SCAN_QTY_WHITESPACE, GET_QTY_FIELD, START_EXECUTION,
262
                        REQUEST_BUS, EXECUTE, DISPLAY_PREP, DISPLAY_ADR,
263
                        DISPLAY_SEPARATOR, DISPLAY_DAT, DISPLAY_SPACE,
264
                        DISPLAY_CRLF, POST_FILL_CYCLE);
265
 
266
signal fsm_state      : FSM_STATE_TYPE;
267
 
268
signal watchdog_timer_done  : std_logic;  -- High when watchdog timer is expired
269
signal char_is_whitespace   : std_logic;  -- High when cmd_buffer[char_count] is whitespace.
270
signal char_is_num          : std_logic;  -- High when cmd_buffer[char_count] is 0..9
271
signal char_is_a_f          : std_logic;  -- High when cmd_buffer[char_count] is a..f
272
signal char_is_hex          : std_logic;  -- High when cmd_buffer[char_count] is a hex char.
273
signal msg_pointer          : unsigned(4 downto 0);  -- Determines message position or address.
274
signal msg_select           : unsigned(4 downto 0);  -- selection of msg_pointer or display value
275
signal hex_digit            : unsigned(3 downto 0);  -- This is the digit to be stored.
276
 
277
signal msg_char             : unsigned(7 downto 0);  -- Selected response message character.
278
signal comment_area         : std_logic;
279
 
280
    -- For the buses
281
signal adr_ptr              : unsigned(4*ADR_DIGITS-1 downto 0);  -- = adr_sr + adr_offset
282
 
283
signal stb_l                : std_logic;  -- "local" stb signal (to distinguish from stb_o)
284
signal we_l                 : std_logic;  -- "local" we  signal (to distinguish from we_o)
285
 
286
signal display_adr_sr       : unsigned(4*ADR_DIGITS-1 downto 0); -- sr for printing addresses
287
signal adr_sr               : unsigned(4*ADR_DIGITS-1 downto 0); -- "nibble" shift register
288
signal dat_sr               : unsigned(4*DAT_DIGITS-1 downto 0); -- "nibble" shift register
289
signal qty_sr               : unsigned(4*QTY_DIGITS-1 downto 0); -- "nibble" shift register
290
 
291
-- The command register has these values
292
type CMD_REG_TYPE is (INIT, READ, FILL, WRITE);
293
signal command : CMD_REG_TYPE;
294
 
295
    -- For the command buffer
296
signal cmd_ptr              : unsigned(CMD_PTR_BITS-1 downto 0); -- Offset from start of command.
297
--signal rd_cmd_ptr           : unsigned(CMD_PTR_BITS-1 downto 0); -- Latched cmd_ptr, use to infer BRAM.
298
type cmd_array_type is
299
  array (integer range 0 to CMD_BUFFER_SIZE-1) of unsigned(7 downto 0);
300
 
301
signal cmd_buffer  : cmd_array_type;
302
signal cmd_char    : unsigned(7 downto 0);
303
signal lc_cmd_char : unsigned(7 downto 0); -- Lowercase version of cmd_char
304
signal adr_offset  : unsigned(4*QTY_DIGITS-1 downto 0);   -- counts from 0 to qty_sr
305
signal adr_freeze  : std_logic; -- When set, prevents adr_offset from incrementing
306
 
307
signal resp_cyc                : std_logic; -- high for response type states
308
signal resp_cyc_l              : std_logic;
309
signal resp_cyc_mask           : std_logic; -- Used to lower resp_cyc_o for one clock cycle, upon acknowledgement.
310
 
311
    -- For various counters
312
signal display_field_count     : unsigned(DISPLAY_FIELD_COUNT_BITS-1 downto 0);      -- "fields displayed"
313
signal display_adr_digit_count : unsigned(DISPLAY_ADR_DIGIT_COUNT_BITS-1 downto 0);  -- "digits displayed"
314
signal display_dat_digit_count : unsigned(DISPLAY_DAT_DIGIT_COUNT_BITS-1 downto 0);  -- "digits displayed"
315
signal watchdog_timer_count    : unsigned(WATCHDOG_TIMER_BITS-1 downto 0);
316
 
317
----------------------------------------------------------------------------
318
-- Component Declarations
319
----------------------------------------------------------------------------
320
 
321
----------------------------------------------------------------------------
322
begin
323
 
324
-- In this module, command characters are accepted immediately but only when in the CHECK_NEW_CHAR state.
325
cmd_ack_o <= '1' when cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR else '0';
326
 
327
-- Provide response character cycle active signal
328
resp_cyc   <= '1' when fsm_state=DISPLAY_CRLF             or
329
                       fsm_state=DISPLAY_SPACE            or
330
                       fsm_state=DISPLAY_DAT              or
331
                       fsm_state=DISPLAY_SEPARATOR        or
332
                       fsm_state=DISPLAY_ADR              or
333
                       fsm_state=SEND_QUESTION            or
334
                       fsm_state=ERR_INDICATOR            or
335
                       fsm_state=PARSE_ERR_INDICATOR_CRLF or
336
                       fsm_state=BG_ERR_INDICATOR         or
337
                       fsm_state=SEND_CRLF                or
338
                       fsm_state=SEND_PROMPT              or
339
                       fsm_state=SEND_OK                  or
340
                       fsm_state=SEND_WELCOME_STRING      else
341
                       '0';
342
-- Implement the "courtesy" of lowering resp_cyc_o for one cycle after resp_ack_i is recognized.
343
-- This increases the amount of time needed for data transfer, and some would say it is needless,
344
-- since a "burst" type transfer also can work.  Since burst transfers were not intended here,
345
-- this is being done anyway.  You see, burst transfers can "tie up" bus arbiters for the entire
346
-- burst, which is not desirable in this design.
347
resp_cyc_l <= '1' when resp_cyc='1' and resp_cyc_mask='0' else '0';
348
resp_cyc_o <= resp_cyc_l;
349
 
350
resp_cyc_mask_proc : process(sys_clk,sys_rst_n)
351
variable i : natural;
352
begin
353
  if (sys_rst_n='0') then
354
    resp_cyc_mask <= '0';
355
  elsif (sys_clk'event and sys_clk='1') then
356
    if (sys_clk_en='1') then
357
      resp_cyc_mask <= '0'; -- Default value
358
      if (resp_cyc_l='1' and resp_ack_i='1') then
359
        resp_cyc_mask <= '1';
360
      end if;
361
    end if;
362
  end if;
363
end process;
364
 
365
 
366
-- Provide command echo indication, to allow ASCII response data to be
367
-- echoed or not, as desired.
368
cmd_echo_o <= '1' when fsm_state=CHECK_NEW_CHAR else '0';
369
 
370
-- Provide parallel ASCII response data
371
resp_char_o <= msg_char;
372
 
373
-- Select which bus signals get used on the system bus
374
adr_o <= adr_ptr when (master_bg_i='1') else master_adr_i;
375
we_o  <= we_l    when (master_bg_i='1') else master_we_i;
376
stb_o <= stb_l   when (master_bg_i='1') else master_stb_i;
377
cyc_o <= stb_l   when (master_bg_i='1') else master_stb_i; -- Separate cyc_o is not yet supported!
378
 
379
dat_o <= dat_sr when (master_bg_i='1' and we_l='1' and stb_l='1') else master_dat_i;
380
master_dat_o <= dat_i;
381
master_ack_o <= ack_i when master_bg_i='0' else '0';
382
 
383
-- This forms the adress pointer which is used on the bus.
384
adr_ptr <= adr_sr + adr_offset when adr_freeze='0' else adr_sr;
385
 
386
-- This is the ROM for the ASCII characters to be transmitted.
387
-- Choose which value to use
388
msg_select <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1)) when fsm_state=DISPLAY_ADR else
389
              '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1))         when fsm_state=DISPLAY_DAT else
390
              msg_pointer;
391
with (msg_select) select
392
  msg_char <=
393
    "00110000" when "00000",  --  "0"; -- Hexadecimal characters
394
    "00110001" when "00001",  --  "1";
395
    "00110010" when "00010",  --  "2";
396
    "00110011" when "00011",  --  "3";
397
    "00110100" when "00100",  --  "4";
398
    "00110101" when "00101",  --  "5";
399
    "00110110" when "00110",  --  "6";
400
    "00110111" when "00111",  --  "7";
401
    "00111000" when "01000",  --  "8";
402
    "00111001" when "01001",  --  "9";
403
    "01000001" when "01010",  --  "A"; -- Address error indication
404
    "01000010" when "01011",  --  "B";
405
    "01000011" when "01100",  --  "C"; -- Command error indication
406
    "01000100" when "01101",  --  "D"; -- Data error indication
407
    "01000101" when "01110",  --  "E";
408
    "01000110" when "01111",  --  "F";
409
    "00100000" when "10000",  --  " "; -- Space
410
    "00111010" when "10001",  --  ":"; -- Colon
411
    "00100000" when "10010",  --  " "; -- Space
412
    "00111111" when "10011",  --  "?"; -- Parse error indication
413
    "00100001" when "10100",  --  "!"; -- ack_i/err_i error indication
414
    "01001111" when "10101",  --  "O"; -- "All is well" message
415
    "01001011" when "10110",  --  "K";
416
    "00001101" when "10111",  -- Carriage Return
417
    "00001010" when "11000",  -- Line Feed
418
    "00101101" when "11001",  --  "-"; -- Command Prompt
419
    "00111110" when "11010",  --  ">";
420
    "00100000" when "11011",  --  " ";
421
    "01010001" when "11100",  --  "Q"; -- Quantity error indication
422
    "01011000" when others;   --  "X";
423
 
424
-- This is state machine m1.  It handles receiving the command line, including
425
-- backspaces, and prints error/response messages.  It also parses and
426
-- executes the commands.
427
 
428
-- State register
429
fsm_proc : process(sys_clk, sys_rst_n)
430
 
431
  procedure exec_prep is
432
  begin
433
    if (adr_offset=qty_sr) then
434
      msg_pointer <= "10101"; -- Address of message
435
      fsm_state   <= SEND_OK;
436
    else
437
      watchdog_timer_count <= (others=>'0'); -- Reset the timer.
438
      fsm_state <= EXECUTE;
439
    end if;
440
  end exec_prep;
441
 
442
begin
443
  if (sys_rst_n='0') then -- asynchronous reset
444
    rst_o       <= '0';
445
    fsm_state   <= IDLE;
446
    command     <= INIT;
447
    msg_pointer <= (others=>'0');
448
    cmd_ptr     <= (others=>'0');
449
    adr_offset  <= (others=>'0');
450
    adr_freeze  <= '0';
451
    adr_sr      <= (others=>'0');
452
    dat_sr      <= (others=>'0');
453
    qty_sr     <= to_unsigned(1,qty_sr'length); -- Set qty = 1 default.
454
    display_field_count      <= (others=>'0');
455
    display_adr_digit_count  <= (others=>'0');
456
    display_dat_digit_count  <= (others=>'0');
457
    watchdog_timer_count     <= (others=>'0');
458
    display_adr_sr           <= (others=>'0');
459
    cmd_done_o  <= '0';
460
    comment_area <= '0';
461
  elsif (sys_clk'event and sys_clk='1') then
462
    if (sys_clk_en='1') then
463
 
464
      -- Handle the Watchdog timer
465
      if (watchdog_timer_done='0') then
466
        watchdog_timer_count <= watchdog_timer_count+1;
467
      end if;
468
 
469
      -- Default values for outputs.  The individual states can override these.
470
      rst_o <= '0';
471
      cmd_done_o <= '0';
472
 
473
      case (fsm_state) is
474
 
475
        when IDLE =>
476
          msg_pointer <= (others=>'0');
477
          fsm_state   <= SEND_WELCOME_STRING;
478
 
479
        when SEND_WELCOME_STRING =>
480
          if (resp_cyc_l='1' and resp_ack_i='1') then
481
            if (msg_pointer=15) then  -- Send initial string ("0123456789ABCDEF")
482
              msg_pointer <= "10111"; -- Address of the message
483
              fsm_state   <= SEND_PROMPT;
484
            else
485
              msg_pointer <= msg_pointer+1;
486
            end if;
487
          end if;
488
 
489
        when SEND_OK =>
490
          if (resp_cyc_l='1' and resp_ack_i='1') then
491
            if (msg_pointer=22) then -- Send 2 characters...
492
              msg_pointer <= "10111"; -- Address of the message
493
              fsm_state   <= SEND_PROMPT;
494
            else
495
              msg_pointer <= msg_pointer+1;
496
            end if;
497
          end if;
498
 
499
        when SEND_PROMPT =>
500
          if (resp_cyc_l='1' and resp_ack_i='1') then
501
            if (msg_pointer=27) then -- Send 5 characters...
502
              cmd_ptr     <= (others=>'0');
503
              cmd_done_o  <= '1';
504
              fsm_state   <= CHECK_NEW_CHAR;
505
            else
506
              msg_pointer <= msg_pointer+1;
507
            end if;
508
          end if;
509
 
510
        -- This state always leads to activating the parser...
511
        when SEND_CRLF =>
512
          if (resp_cyc_l='1' and resp_ack_i='1') then
513
            if (msg_pointer=24) then -- Send 2 characters...
514
              cmd_ptr     <= (others=>'0');
515
              fsm_state   <= SCAN_CMD;
516
            else
517
              msg_pointer <= msg_pointer+1;
518
            end if;
519
          end if;
520
 
521
        when CHECK_NEW_CHAR =>
522
          if (cmd_we_i='1') then
523
            if (cmd_char_i=BACKSPACE_CHAR) then
524
              cmd_ptr <= cmd_ptr-1; -- This effectively eliminates the last char
525
            elsif (comment_area='0' and cmd_char_i=ENTER_CHAR) or (cmd_ptr=CMD_BUFFER_SIZE-1) then
526
              if (cmd_char_i=ENTER_CHAR) then
527
                msg_pointer <= "10111";     -- Address of the message
528
                fsm_state   <= SEND_CRLF;
529
              end if;
530
              if (cmd_ptr=CMD_BUFFER_SIZE-1) then
531
                msg_pointer <= "10111";    -- Address of the message.
532
                cmd_ptr     <= (others=>'0');
533
                fsm_state   <= PARSE_ERR_INDICATOR_CRLF;
534
              end if;
535
            elsif (cmd_char_i=COMMENT_CHAR) then
536
              comment_area <= '1'; -- Activate comment area, which stores characters, but does not advance cmd_ptr.
537
            elsif (comment_area='0') then
538
              cmd_ptr <= cmd_ptr+1;
539
            end if;
540
            -- Deactivate comment area at end of line
541
            if (comment_area='1' and cmd_char_i=ENTER_CHAR) then
542
              comment_area <= '0';
543
              -- Check if a valid command might have preceded the comment
544
              if (cmd_ptr>1) then
545
                msg_pointer <= "10111";     -- Address of the message
546
                fsm_state   <= SEND_CRLF;
547
              else
548
                msg_pointer <= "10111"; -- Address of the message
549
                fsm_state   <= SEND_PROMPT;
550
              end if;
551
            end if;
552
          end if;
553
 
554
        when BG_ERR_INDICATOR =>
555
          if (resp_cyc_l='1' and resp_ack_i='1') then
556
            msg_pointer <= "10100";    -- Address of the error message
557
            fsm_state   <= ERR_INDICATOR;
558
          end if;
559
 
560
        -- This state is used when the line is too long...
561
        when PARSE_ERR_INDICATOR_CRLF =>
562
          if (resp_cyc_l='1' and resp_ack_i='1') then
563
            if (msg_pointer=24) then -- Send 2 characters...
564
              msg_pointer <= "10011";    -- Address of the message.
565
              fsm_state   <= ERR_INDICATOR;
566
            else
567
              msg_pointer <= msg_pointer+1;
568
            end if;
569
          end if;
570
 
571
        when ERR_INDICATOR =>
572
          if (resp_cyc_l='1' and resp_ack_i='1') then
573
            msg_pointer <= "10111"; -- Address of the message
574
            fsm_state   <= SEND_PROMPT;
575
          end if;
576
 
577
        when SEND_QUESTION =>
578
          if (resp_cyc_l='1' and resp_ack_i='1') then
579
            msg_pointer <= "10011";    -- Address of the message.
580
            fsm_state   <= ERR_INDICATOR;
581
          end if;
582
 
583
        -- The following states are for parsing and executing the command.
584
 
585
        -- This state takes care of leading whitespace before the command
586
        when SCAN_CMD =>
587
          cmd_ptr    <= cmd_ptr+1;
588
          adr_offset <= (others=>'0');
589
          case (lc_cmd_char) is
590
            when "01110010" => -- "r"
591
              command   <= READ;
592
              fsm_state <= CHECK_SUFFICES;
593
            when "01110111" => -- "w"
594
              command   <= WRITE;
595
              qty_sr    <= (others=>'1'); -- Limit writes to the max. qty...
596
              fsm_state <= CHECK_SUFFICES;
597
            when "01101001" => -- "i"
598
              command   <= INIT;
599
              qty_sr    <= (others=>'0');
600
              rst_o     <= '1'; -- Actually do this one right now!!
601
              fsm_state <= START_EXECUTION;
602
            when "01100110" => -- "f"
603
              command   <= FILL;
604
              fsm_state <= CHECK_SUFFICES;
605
            when others     =>
606
              if (char_is_whitespace='0') then
607
                msg_pointer <= "01100";    -- Address of message
608
                fsm_state   <= SEND_QUESTION;
609
              end if;
610
          end case;
611
 
612
        -- This state cleverly detects command "suffix" modifiers, such
613
        -- as the '0' modifier, which causes the address to remain frozen.
614
        -- Invalid or unimplemented suffix modifiers elicit the "C?" response.
615
        when CHECK_SUFFICES => -- Should that read "check suffixes" Hmmm...
616
          if (cmd_char="00110000") then -- '0' suffix
617
            cmd_ptr <= cmd_ptr+1;
618
            adr_freeze <= '1';
619
            fsm_state <= SCAN_ADR_WHITESPACE;
620
          elsif (cmd_char=ENTER_CHAR) then
621
            fsm_state <= START_EXECUTION; -- Using last values
622
          elsif (char_is_whitespace='1') then
623
            adr_freeze <= '0';
624
            fsm_state <= SCAN_ADR_WHITESPACE;
625
          else
626
            msg_pointer <= "01100";    -- Address of message
627
            fsm_state   <= SEND_QUESTION;
628
          end if;
629
 
630
 
631
        -- The only way to determine the end of a valid field is to find
632
        -- whitespace.  Therefore, char_is_whitespace must be used as an exit
633
        -- condition from the "get_xxx_field" states.  So, this state is used to
634
        -- scan through any leading whitespace prior to the first field.
635
        when SCAN_ADR_WHITESPACE =>
636
          if (char_is_whitespace='1') then
637
            cmd_ptr <= cmd_ptr+1;
638
          elsif (cmd_char=ENTER_CHAR) then
639
            fsm_state <= START_EXECUTION; -- Using last values
640
          else
641
            fsm_state <= GET_ADR_FIELD;
642
            adr_sr    <= (others=>'0');
643
          end if;
644
 
645
        when GET_ADR_FIELD =>
646
          if (char_is_hex='1') then
647
            adr_sr    <= adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & hex_digit;
648
            cmd_ptr   <= cmd_ptr+1;
649
          elsif (char_is_whitespace='1') then -- Normal exit
650
            fsm_state <= SCAN_DAT_WHITESPACE;
651
          elsif (cmd_char=ENTER_CHAR and command=READ) then
652
            fsm_state <= START_EXECUTION; -- Using last values
653
          else
654
            msg_pointer <= "01010";    -- Address of message
655
            fsm_state   <= SEND_QUESTION;
656
          end if;
657
 
658
        when SCAN_DAT_WHITESPACE =>
659
          -- There is no DAT field for reads, so skip it.
660
          if (command=READ) then
661
            fsm_state <= SCAN_QTY_WHITESPACE;
662
          elsif (char_is_whitespace='1') then
663
            cmd_ptr <= cmd_ptr+1;
664
          elsif (cmd_char=ENTER_CHAR) then
665
            if (command=WRITE) then -- Writing data values done, finish.
666
              msg_pointer <= "10101";    -- Address of message
667
              fsm_state   <= SEND_OK;
668
            else
669
              fsm_state <= START_EXECUTION; -- Using last DATA & QTY values
670
            end if;
671
          else
672
            fsm_state <= GET_DAT_FIELD;
673
            dat_sr    <= (others=>'0');
674
          end if;
675
 
676
        when GET_DAT_FIELD =>
677
          if (char_is_hex='1') then
678
            dat_sr    <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
679
            cmd_ptr   <= cmd_ptr+1;
680
          elsif (char_is_whitespace='1') then -- Normal exit
681
            if (command=WRITE) then
682
              fsm_state  <= START_EXECUTION;
683
            else
684
              fsm_state <= SCAN_QTY_WHITESPACE;
685
            end if;
686
          elsif (cmd_char=ENTER_CHAR) then
687
            fsm_state <= START_EXECUTION;
688
          else
689
            msg_pointer <= "01101";    -- Address of message
690
            fsm_state   <= SEND_QUESTION;
691
          end if;
692
 
693
        when SCAN_QTY_WHITESPACE =>
694
          if (char_is_whitespace='1') then
695
            cmd_ptr   <= cmd_ptr+1;
696
          elsif (cmd_char=ENTER_CHAR) then
697
            fsm_state <= START_EXECUTION; -- Using last values
698
          else
699
            fsm_state <= GET_QTY_FIELD;
700
            qty_sr    <= to_unsigned(0,qty_sr'length);
701
          end if;
702
 
703
        when GET_QTY_FIELD =>
704
          if (char_is_hex='1') then
705
            qty_sr    <= qty_sr(4*(QTY_DIGITS-1)-1 downto 0) & hex_digit;
706
            cmd_ptr   <= cmd_ptr+1;
707
          elsif (char_is_whitespace='1' or cmd_char=ENTER_CHAR) then  -- Normal exit
708
            fsm_state <= START_EXECUTION;
709
          else
710
            msg_pointer <= "11100";    -- Address of message
711
            fsm_state   <= SEND_QUESTION;
712
          end if;
713
 
714
        -- This state seeks to obtain master_bg_i, which grants the bus for use.
715
        when START_EXECUTION =>
716
          watchdog_timer_count <= (others=>'0'); -- Reset the timer.
717
          display_adr_sr       <= adr_ptr;
718
          display_field_count  <= (others=>'0');
719
          if (master_bg_i='1') then -- skip REQUEST_BUS if it is already granted!
720
            exec_prep;
721
          else
722
            fsm_state   <= REQUEST_BUS;
723
          end if;
724
 
725
        when REQUEST_BUS =>
726
          if (master_bg_i='1') then
727
            exec_prep; -- resets watchdog, sends "OK" if done.
728
          elsif (watchdog_timer_done='1') then
729
            msg_pointer <= "01011";    -- Address of messsage
730
            fsm_state   <= BG_ERR_INDICATOR;
731
          end if;
732
 
733
        -- This single state does fill/write/read depending upon the value
734
        -- contained in "command"!
735
        when EXECUTE =>
736
          if (watchdog_timer_done='1' or err_i='1') then
737
            fsm_state   <= BG_ERR_INDICATOR;
738
          elsif (ack_i='1' and master_bg_i='1') then
739
            case command is
740
              when READ =>
741
                dat_sr <= dat_i; -- Capture the read data
742
                display_adr_sr <= adr_ptr;
743
                fsm_state <= DISPLAY_PREP;
744
              when WRITE =>
745
                adr_offset <= adr_offset+1;
746
                fsm_state  <= SCAN_DAT_WHITESPACE; -- Continue to next data value
747
              when FILL  =>
748
                adr_offset <= adr_offset+1;
749
                fsm_state  <= POST_FILL_CYCLE;
750
              when others =>
751
                fsm_state  <= POST_FILL_CYCLE;
752
            end case;
753
          end if;
754
 
755
        when POST_FILL_CYCLE =>
756
          exec_prep; -- resets watchdog, sends "OK" if done.
757
 
758
        when DISPLAY_PREP =>
759
          adr_offset <= adr_offset+1;
760
          if (display_field_count = 0) then -- Check to see if address display is needed yet.
761
            msg_pointer <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1));
762
            display_adr_digit_count <= (others=>'0');
763
            display_adr_sr <= adr_ptr;
764
            fsm_state <= DISPLAY_ADR; -- Leads to a new address line.
765
          else
766
            display_dat_digit_count <= (others=>'0');
767
            msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
768
            fsm_state <= DISPLAY_DAT;
769
          end if;
770
 
771
        when DISPLAY_ADR =>
772
          if (resp_cyc_l='1' and resp_ack_i='1') then
773
            if (display_adr_digit_count = ADR_DIGITS-1) then
774
              msg_pointer <= "10000";    -- Address of the message
775
              fsm_state   <= DISPLAY_SEPARATOR;
776
            else
777
              display_adr_sr <= display_adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & to_unsigned(0,4);
778
              display_adr_digit_count <= display_adr_digit_count+1;
779
            end if;
780
          end if;
781
 
782
        when DISPLAY_SEPARATOR =>
783
          if (resp_cyc_l='1' and resp_ack_i='1') then
784
            msg_pointer <= msg_pointer+1;
785
            if (msg_pointer = 18) then -- Three characters
786
              display_dat_digit_count <= (others=>'0');
787
              msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
788
              fsm_state <= DISPLAY_DAT;
789
            end if;
790
          end if;
791
 
792
        when DISPLAY_DAT =>
793
          if (resp_cyc_l='1' and resp_ack_i='1') then
794
            if (
795
                (display_dat_digit_count = DAT_DIGITS-1)
796
                and (display_field_count = DISPLAY_FIELDS-1)
797
                )
798
            then
799
              msg_pointer <= "10111";     -- Address of the message
800
              fsm_state   <= DISPLAY_CRLF;
801
              display_field_count <= (others=>'0');
802
            elsif (display_dat_digit_count = DAT_DIGITS-1) then
803
              msg_pointer <= "10000";    -- Address of the message
804
              fsm_state   <= DISPLAY_SPACE;
805
              display_field_count <= display_field_count+1;
806
            else
807
              dat_sr      <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
808
              display_dat_digit_count <= display_dat_digit_count+1;
809
            end if;
810
          end if;
811
 
812
        when DISPLAY_SPACE =>
813
          if (resp_cyc_l='1' and resp_ack_i='1') then
814
            exec_prep; -- resets watchdog, sends "OK" if done.
815
          end if;
816
 
817
        when DISPLAY_CRLF =>
818
          if (resp_cyc_l='1' and resp_ack_i='1') then
819
            msg_pointer <= msg_pointer+1;
820
            if (msg_pointer=24) then -- Two characters
821
              exec_prep; -- resets watchdog, sends "OK" if done.
822
            end if;
823
          end if;
824
 
825
        --when others => 
826
        --  fsm_state <= IDLE;
827
      end case;
828
 
829
    end if; -- sys_clk_en
830
  end if; -- sys_clk
831
end process;
832
 
833
-- Assert needed outputs during execution of bus cycles
834
master_br_o <= '1' when (fsm_state=REQUEST_BUS or fsm_state=EXECUTE) else '0';
835
we_l        <= '1' when (fsm_state=EXECUTE and (command=WRITE or command=FILL)) else '0';
836
stb_l       <= '1' when (fsm_state=EXECUTE) else '0';
837
 
838
 
839
-- This is the command buffer writing section
840
ram_proc : process(sys_clk,sys_rst_n)
841
variable i : natural;
842
begin
843
  if (sys_rst_n='0') then
844
    -- synthesis translate_off
845
    -- The initialization of the command buffer is for convenience in simulation only.
846
    -- It can be removed for synthesis.
847
     for i in 0 to CMD_BUFFER_SIZE-1 loop
848
       cmd_buffer(i) <= (others=>'0');
849
     end loop;
850
    -- synthesis translate_on
851
  elsif (sys_clk'event and sys_clk='1') then
852
    if (sys_clk_en='1') then
853
      if (cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR) then
854
        cmd_buffer(to_integer(cmd_ptr)) <= cmd_char_i;
855
      end if;
856
      -- Latch the command pointer, for synchronous reads.
857
      --rd_cmd_ptr <= cmd_ptr; -- Use this to infer BRAM.
858
    end if;
859
  end if;
860
end process;
861
 
862
-- This is the command buffer reading section
863
cmd_char <= cmd_buffer(to_integer(cmd_ptr)); -- Asynchronous read.  Amazingly, this was the better option in XC2S200E...
864
--cmd_char <= cmd_buffer(to_integer(rd_cmd_ptr)); -- Synchronous read, use this to infer BRAM.
865
lc_cmd_char <= (cmd_char or "00100000"); -- lowercase
866
 
867
-- These assigments are for detecting whether the cmd_char is
868
-- anything of special interest.
869
char_is_whitespace <= '1' when ((cmd_char=16#20#)  -- space
870
                             or (cmd_char=16#09#)  -- tab
871
                             or (cmd_char=16#0A#)  -- line feed
872
                       ) else '0';
873
char_is_num <= '1' when ((cmd_char>=16#30#) and (cmd_char<=16#39#)) else '0';
874
char_is_a_f <= '1' when ((lc_cmd_char>=16#61#) and (lc_cmd_char<=16#66#)) else '0';
875
char_is_hex <= char_is_num or char_is_a_f;
876
 
877
hex_digit <= cmd_char(3 downto 0) when char_is_num='1' else (cmd_char(3 downto 0)+"1001");
878
 
879
watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG_VALUE) else '0';
880
 
881
end beh;
882
 
883
 
884
---------------------------------------------------------------------------------------
885
--
886
-- Author: John Clayton
887
-- Date  : Nov. 20, 2009
888
-- Update: 11/20/09 copied this file from rs232_syscon.v  Began translating.
889
--         10/04/11 Removed msg_offset+msg_base adder, in a bid to
890
--                  increase max operating speed of this module.
891
--                  Combined CMD_ERR_INDICATOR, ADR_ERR_INDICATOR,
892
--                           DAT_ERR_INDICATOR, and QTY_ERR_INDICATOR
893
--                  into a single state : SEND_QUESTION
894
--                  Combined ACK_ERR_INDICATOR and PARSE_ERR_INDICATOR
895
--                  into a single state : ERR_INDICATOR
896
--         08/03/13 Removed rs232_tx_active_o, since it appears to be a
897
--                  vestigial relic of a time long ago when the echoing of
898
--                  command characters was done through the UART, and not
899
--                  directly as it is now.  It was staying high all the
900
--                  time except for brief pulses low during generated
901
--                  responses... which is not useful.
902
--         08/03/13 Added "cmd_done_o" output pulse, which helps outside
903
--                  serial command generators know when to begin generating
904
--                  the next command.  Removed the "rs232_" prefix from
905
--                  signal names, since the signals really aren't at RS232
906
--                  levels.
907
--         08/03/13 Changed module and packet name to replace "rs232_"
908
--                  with "async_"
909
--         08/07/13 Added logic to include a "single line" type of comment
910
--                  which allows initialization strings and messages to
911
--                  include comments, which are echoed back over the
912
--                  interface for the user to perhaps see.
913
--
914
-- Description
915
---------------------------------------------------------------------------------------
916
-- This module takes an "ascii_syscon" unit and adds an asynchronous serial
917
-- interface to it.
918
--
919
-- For details of command and response syntax, please refer to the ascii_syscon
920
-- description.
921
--
922
---------------------------------------------------------------------------------------
923
 
924
library IEEE;
925
use IEEE.STD_LOGIC_1164.ALL;
926
use IEEE.NUMERIC_STD.ALL;
927
use IEEE.MATH_REAL.ALL;
928
 
929
entity async_syscon is
930
    generic (
931
      ECHO_COMMANDS   : natural :=         1; -- set nonzero to echo back command characters
932
      ADR_DIGITS      : natural :=         4; -- # of hex digits for address
933
      DAT_DIGITS      : natural :=         4; -- # of hex digits for data
934
      QTY_DIGITS      : natural :=         2; -- # of hex digits for quantity
935
      CMD_BUFFER_SIZE : natural :=        32; -- # of chars in the command buffer
936
      WATCHDOG_VALUE  : natural :=       200; -- # of sys_clks before ack is expected
937
      DISPLAY_FIELDS  : natural :=         8  -- # of fields/line
938
    );
939
    port (
940
 
941
      sys_rst_n    : in  std_logic;
942
      sys_clk      : in  std_logic;
943
      sys_clk_en   : in  std_logic;
944
 
945
      -- rate and parity
946
      parity_i     : in  unsigned(1 downto 0); -- 0=none, 1=even, 2=odd
947
      baud_clk_i   : in  std_logic; -- At 1x the desired baud rate, can be squarewave or pulses.
948
      baud_lock_i  : in  std_logic; -- '1' Indicates baud clock is stable and ready.
949
 
950
      -- Serial IO
951
      cmd_i        : in  std_logic;
952
      resp_o       : out std_logic;
953
      cmd_done_o   : out std_logic;
954
 
955
      -- Master Bus IO
956
      master_bg_i  : in  std_logic;
957
      master_ack_o : out std_logic;
958
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
959
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
960
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
961
      master_stb_i : in  std_logic;
962
      master_we_i  : in  std_logic;
963
      master_br_o  : out std_logic;
964
 
965
      -- System Bus IO
966
      ack_i        : in  std_logic;
967
      err_i        : in  std_logic;
968
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
969
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
970
      rst_o        : out std_logic;
971
      stb_o        : out std_logic;
972
      cyc_o        : out std_logic;
973
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
974
      we_o         : out std_logic
975
    );
976
end async_syscon;
977
 
978
architecture beh of async_syscon is
979
 
980
-- Constants
981
constant ENTER_CHAR : unsigned := "00001101";
982
 
983
-- Signals
984
  -- For ascii_syscon
985
signal cmd_char         : unsigned(7 downto 0);
986
signal cmd_we_uart      : std_logic;
987
signal cmd_we_wait      : std_logic;
988
signal cmd_rx_done      : std_logic;
989
signal cmd_we           : std_logic;
990
signal cmd_ack          : std_logic;
991
signal cmd_echo         : std_logic;
992
signal resp_char        : unsigned(7 downto 0);
993
signal resp_cyc         : std_logic;
994
signal resp_cyc_r1      : std_logic;
995
signal resp_cyc_uart    : std_logic;
996
signal resp_ack_uart    : std_logic;
997
signal resp_ack_uart_r1 : std_logic;
998
signal resp_ack         : std_logic;
999
 
1000
  -- For the serial interface
1001
signal async_rx_error       : unsigned(1 downto 0);
1002
signal async_rx_restart     : std_logic;
1003
signal resp_l               : std_logic;
1004
 
1005
----------------------------------------------------------------------------
1006
-- Component Declarations
1007
----------------------------------------------------------------------------
1008
 
1009
----------------------------------------------------------------------------
1010
begin
1011
 
1012
----------------------------------------------------------------------------
1013
-- Instantiations
1014
----------------------------------------------------------------------------
1015
 
1016
uart1 : entity work.uart_sqclk(beh)
1017
    port map (
1018
 
1019
      sys_rst_n     => sys_rst_n,
1020
      sys_clk       => sys_clk,
1021
      sys_clk_en    => sys_clk_en,
1022
 
1023
      -- rate and parity
1024
      parity_i      => parity_i,
1025
      rate_clk_i    => baud_clk_i,
1026
 
1027
      -- serial I/O
1028
      tx_stream     => resp_l,
1029
      rx_stream     => cmd_i,
1030
 
1031
      --control and status
1032
      tx_wr_i       => resp_cyc_uart,
1033
      tx_dat_i      => resp_char,
1034
      tx_done_o     => resp_ack_uart,
1035
      rx_restart_i  => async_rx_restart,   -- High clears error flags, clears rx_done_o
1036
      rx_dat_o      => cmd_char,
1037
      rx_wr_o       => cmd_we_uart,        -- High pulse means store rx_dat_o.
1038
      rx_done_o     => cmd_rx_done,        -- Remains high after receive, until clk edge with rx_restart_i=1
1039
      frame_err_o   => async_rx_error(0),  -- High = error.  Reset when rx_restart_i asserted.
1040
      parity_err_o  => async_rx_error(1)   -- High = error.  Reset when rx_restart_i asserted.
1041
    );
1042
 
1043
syscon1 : entity work.ascii_syscon(beh)
1044
    generic map(
1045
      ADR_DIGITS      => ADR_DIGITS, -- # of hex digits for address
1046
      DAT_DIGITS      => DAT_DIGITS, -- # of hex digits for data
1047
      QTY_DIGITS      => QTY_DIGITS, -- # of hex digits for quantity
1048
      CMD_BUFFER_SIZE => CMD_BUFFER_SIZE, -- # of chars in the command buffer
1049
      WATCHDOG_VALUE  => WATCHDOG_VALUE, -- # of sys_clks before ack is expected
1050
      DISPLAY_FIELDS  => DISPLAY_FIELDS -- # of fields/line
1051
    )
1052
    port map(
1053
 
1054
      sys_rst_n    => sys_rst_n,
1055
      sys_clk      => sys_clk,
1056
      sys_clk_en   => sys_clk_en,
1057
 
1058
      -- Parallel ASCII I/O
1059
      cmd_char_i   => cmd_char,
1060
      cmd_we_i     => cmd_we,
1061
      cmd_ack_o    => cmd_ack,
1062
      cmd_echo_o   => cmd_echo,
1063
      resp_char_o  => resp_char,
1064
      resp_cyc_o   => resp_cyc,
1065
      resp_ack_i   => resp_ack,
1066
      cmd_done_o   => cmd_done_o,
1067
 
1068
      -- Master Bus IO
1069
      master_bg_i  => master_bg_i,
1070
      master_ack_o => master_ack_o,
1071
      master_adr_i => master_adr_i,
1072
      master_dat_i => master_dat_i,
1073
      master_dat_o => master_dat_o,
1074
      master_stb_i => master_stb_i,
1075
      master_we_i  => master_we_i,
1076
      master_br_o  => master_br_o,
1077
 
1078
      -- System Bus IO
1079
      ack_i        => ack_i,
1080
      err_i        => err_i,
1081
      dat_i        => dat_i,
1082
      dat_o        => dat_o,
1083
      rst_o        => rst_o,
1084
      stb_o        => stb_o,
1085
      cyc_o        => cyc_o,
1086
      adr_o        => adr_o,
1087
      we_o         => we_o
1088
    );
1089
 
1090
----------------------------------------------------------------------------
1091
-- Module code
1092
----------------------------------------------------------------------------
1093
 
1094
async_rx_restart <= async_rx_error(0) or async_rx_error(1) or cmd_ack;
1095
resp_o <= resp_l when cmd_echo='0' else
1096
          cmd_i  when ECHO_COMMANDS/=0 else
1097
          '1';
1098
 
1099
  -- Detect rising edge of resp_ack_uart
1100
  resp_ack_proc: Process(sys_rst_n,sys_clk)
1101
  begin
1102
    if (sys_rst_n = '0') then
1103
      resp_ack_uart_r1 <= '1';
1104
    elsif (sys_clk'event AND sys_clk='1') then
1105
      if (sys_clk_en='1') then
1106
        resp_ack_uart_r1 <= resp_ack_uart;
1107
      end if;
1108
    end if; -- sys_clk
1109
  end process;
1110
  resp_ack <= '1' when resp_ack_uart='1' and resp_ack_uart_r1='0' else '0';
1111
 
1112
  -- Detect rising edge of resp_cyc
1113
  resp_cyc_proc: Process(sys_rst_n,sys_clk)
1114
  begin
1115
    if (sys_rst_n = '0') then
1116
      resp_cyc_r1 <= '1';
1117
    elsif (sys_clk'event AND sys_clk='1') then
1118
      if (sys_clk_en='1') then
1119
        resp_cyc_r1 <= resp_cyc;
1120
      end if;
1121
    end if; -- sys_clk
1122
  end process;
1123
  resp_cyc_uart <= '1' when resp_cyc='1' and resp_cyc_r1='0' else '0';
1124
 
1125
  -- Create a valid command write enable, that waits until the final echoed
1126
  -- character (CHAR_ENTER) is done being transmitted
1127
  cmd_we_proc: Process(sys_rst_n,sys_clk)
1128
  begin
1129
    if (sys_rst_n = '0') then
1130
      cmd_we_wait <= '0';
1131
    elsif (sys_clk'event AND sys_clk='1') then
1132
      if (sys_clk_en='1') then
1133
        if (cmd_we_uart='1' and cmd_we_wait='0') then
1134
          cmd_we_wait <= '1';
1135
        end if;
1136
        if (cmd_we_wait='1') then
1137
          if (cmd_rx_done='1') then
1138
            cmd_we_wait <= '0';
1139
          end if;
1140
        end if;
1141
      end if;
1142
    end if; -- sys_clk
1143
  end process;
1144
 
1145
cmd_we <= cmd_we_uart when baud_lock_i='1' and cmd_char/=ENTER_CHAR else
1146
          '1'         when baud_lock_i='1' and cmd_char=ENTER_CHAR and cmd_we_wait='1' and cmd_rx_done='1' else
1147
          '0';
1148
 
1149
end beh;
1150
 
1151
 

powered by: WebSVN 2.1.0

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